SUMO - Simulation of Urban MObility
NWWriter_DlrNavteq.cpp
Go to the documentation of this file.
1 /****************************************************************************/
8 // Exporter writing networks using DlrNavteq (Elmar) format
9 /****************************************************************************/
10 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
11 // Copyright (C) 2012-2015 DLR (http://www.dlr.de/) and contributors
12 /****************************************************************************/
13 //
14 // This file is part of SUMO.
15 // SUMO is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation, either version 3 of the License, or
18 // (at your option) any later version.
19 //
20 /****************************************************************************/
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #ifdef _MSC_VER
27 #include <windows_config.h>
28 #else
29 #include <config.h>
30 #endif
31 #include <algorithm>
32 #include <ctime>
33 #include <cmath>
35 #include <netbuild/NBEdge.h>
36 #include <netbuild/NBEdgeCont.h>
37 #include <netbuild/NBNode.h>
38 #include <netbuild/NBNodeCont.h>
39 #include <netbuild/NBNetBuilder.h>
40 #include <utils/common/ToString.h>
45 #include "NWFrame.h"
46 #include "NWWriter_DlrNavteq.h"
47 
48 #ifdef CHECK_MEMORY_LEAKS
49 #include <foreign/nvwa/debug_new.h>
50 #endif // CHECK_MEMORY_LEAKS
51 
52 
53 // ---------------------------------------------------------------------------
54 // static members
55 // ---------------------------------------------------------------------------
56 const std::string NWWriter_DlrNavteq::UNDEFINED("-1");
57 
58 // ---------------------------------------------------------------------------
59 // static methods
60 // ---------------------------------------------------------------------------
61 void
63  // check whether a matsim-file shall be generated
64  if (!oc.isSet("dlr-navteq-output")) {
65  return;
66  }
70 }
71 
72 
74  time_t rawtime;
75  time(&rawtime);
76  char buffer [80];
77  strftime(buffer, 80, "on %c", localtime(&rawtime));
78  device << "# Generated " << buffer << " by " << oc.getFullName() << "\n";
79  device << "# Format matches Extraction version: V6.0 \n";
80  std::stringstream tmp;
81  oc.writeConfiguration(tmp, true, false, false);
82  tmp.seekg(std::ios_base::beg);
83  std::string line;
84  while (!tmp.eof()) {
85  std::getline(tmp, line);
86  device << "# " << line << "\n";
87  }
88  device << "#\n";
89 }
90 
91 void
93  // For "real" nodes we simply use the node id.
94  // For internal nodes (geometry vectors describing edge geometry in the parlance of this format)
95  // we use the id of the edge and do not bother with
96  // compression (each direction gets its own internal node).
97  // XXX add option for generating numerical ids in case the input network has string ids and the target process needs integers
98  OutputDevice& device = OutputDevice::getDevice(oc.getString("dlr-navteq-output") + "_nodes_unsplitted.txt");
99  writeHeader(device, oc);
100  const GeoConvHelper& gch = GeoConvHelper::getFinal();
101  const bool haveGeo = gch.usingGeoProjection();
102  const SUMOReal geoScale = pow(10.0f, haveGeo ? 5 : 2); // see NIImporter_DlrNavteq::GEO_SCALE
103  device.setPrecision(0);
104  if (!haveGeo) {
105  WRITE_WARNING("DlrNavteq node data will be written in (floating point) cartesian coordinates");
106  }
107  // write format specifier
108  device << "# NODE_ID\tIS_BETWEEN_NODE\tamount_of_geocoordinates\tx1\ty1\t[x2 y2 ... xn yn]\n";
109  // write normal nodes
110  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
111  NBNode* n = (*i).second;
112  Position pos = n->getPosition();
113  gch.cartesian2geo(pos);
114  pos.mul(geoScale);
115  device << n->getID() << "\t0\t1\t" << pos.x() << "\t" << pos.y() << "\n";
116  }
117  // write "internal" nodes
118  for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) {
119  NBEdge* e = (*i).second;
120  const PositionVector& geom = e->getGeometry();
121  if (geom.size() > 2) {
122  std::string internalNodeID = e->getID();
123  if (internalNodeID == UNDEFINED ||
124  (nc.retrieve(internalNodeID) != 0)) {
125  // need to invent a new name to avoid clashing with the id of a 'real' node or a reserved name
126  internalNodeID += "_geometry";
127  }
128  device << internalNodeID << "\t1\t" << geom.size() - 2;
129  for (size_t ii = 1; ii < geom.size() - 1; ++ii) {
130  Position pos = geom[(int)ii];
131  gch.cartesian2geo(pos);
132  pos.mul(geoScale);
133  device << "\t" << pos.x() << "\t" << pos.y();
134  }
135  device << "\n";
136  }
137  }
138  device.close();
139 }
140 
141 
142 void
144  std::map<const std::string, std::string> nameIDs;
145  OutputDevice& device = OutputDevice::getDevice(oc.getString("dlr-navteq-output") + "_links_unsplitted.txt");
146  writeHeader(device, oc);
147  // write format specifier
148  device << "# LINK_ID\tNODE_ID_FROM\tNODE_ID_TO\tBETWEEN_NODE_ID\tLENGTH\tVEHICLE_TYPE\tFORM_OF_WAY\tBRUNNEL_TYPE\tFUNCTIONAL_ROAD_CLASS\tSPEED_CATEGORY\tNUMBER_OF_LANES\tSPEED_LIMIT\tSPEED_RESTRICTION\tNAME_ID1_REGIONAL\tNAME_ID2_LOCAL\tHOUSENUMBERS_RIGHT\tHOUSENUMBERS_LEFT\tZIP_CODE\tAREA_ID\tSUBAREA_ID\tTHROUGH_TRAFFIC\tSPECIAL_RESTRICTIONS\tEXTENDED_NUMBER_OF_LANES\tISRAMP\tCONNECTION\n";
149  // write edges
150  for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) {
151  NBEdge* e = (*i).second;
152  const int kph = speedInKph(e->getSpeed());
153  const std::string& betweenNodeID = (e->getGeometry().size() > 2) ? e->getID() : UNDEFINED;
154  std::string nameID = UNDEFINED;
155  if (oc.getBool("output.street-names")) {
156  const std::string& name = i->second->getStreetName();
157  if (name != "" && nameIDs.count(name) == 0) {
158  nameID = toString(nameIDs.size());
159  nameIDs[name] = nameID;
160  }
161  }
162  device << e->getID() << "\t"
163  << e->getFromNode()->getID() << "\t"
164  << e->getToNode()->getID() << "\t"
165  << betweenNodeID << "\t"
166  << getGraphLength(e) << "\t"
167  << getAllowedTypes(e->getPermissions()) << "\t"
168  << "3\t" // Speed Category 1-8 XXX refine this
169  << UNDEFINED << "\t" // no special brunnel type (we don't know yet)
170  << getRoadClass(e) << "\t"
171  << getSpeedCategory(kph) << "\t"
172  << getNavteqLaneCode(e->getNumLanes()) << "\t"
173  << getSpeedCategoryUpperBound(kph) << "\t"
174  << kph << "\t"
175  << nameID << "\t" // NAME_ID1_REGIONAL XXX
176  << UNDEFINED << "\t" // NAME_ID2_LOCAL XXX
177  << UNDEFINED << "\t" // housenumbers_right
178  << UNDEFINED << "\t" // housenumbers_left
179  << UNDEFINED << "\t" // ZIP_CODE
180  << UNDEFINED << "\t" // AREA_ID
181  << UNDEFINED << "\t" // SUBAREA_ID
182  << "1\t" // through_traffic (allowed)
183  << UNDEFINED << "\t" // special_restrictions
184  << UNDEFINED << "\t" // extended_number_of_lanes
185  << UNDEFINED << "\t" // isRamp
186  << "0\t" // connection (between nodes always in order)
187  << "\n";
188  }
189  if (oc.getBool("output.street-names")) {
190  OutputDevice& namesDevice = OutputDevice::getDevice(oc.getString("dlr-navteq-output") + "_names.txt");
191  writeHeader(namesDevice, oc);
192  // write format specifier
193  namesDevice << "# NAME_ID\tName\n" << nameIDs.size() << "\n";
194  for (std::map<const std::string, std::string>::const_iterator i = nameIDs.begin(); i != nameIDs.end(); ++i) {
195  namesDevice << i->second << "\t" << i->first << "\n";
196  }
197  }
198 }
199 
200 
201 std::string
203  if (permissions == SVCAll) {
204  return "100000000000";
205  }
206  std::ostringstream oss;
207  oss << "0";
208  oss << ((permissions & SVC_PASSENGER) > 0 ? 1 : 0);
209  oss << ((permissions & SVC_PASSENGER) > 0 ? 1 : 0); // residential
210  oss << ((permissions & SVC_HOV) > 0 ? 1 : 0);
211  oss << ((permissions & SVC_EMERGENCY) > 0 ? 1 : 0);
212  oss << ((permissions & SVC_TAXI) > 0 ? 1 : 0);
213  oss << ((permissions & (SVC_BUS | SVC_COACH)) > 0 ? 1 : 0);
214  oss << ((permissions & SVC_DELIVERY) > 0 ? 1 : 0);
215  oss << ((permissions & (SVC_TRUCK | SVC_TRAILER)) > 0 ? 1 : 0);
216  oss << ((permissions & SVC_MOTORCYCLE) > 0 ? 1 : 0);
217  oss << ((permissions & SVC_BICYCLE) > 0 ? 1 : 0);
218  oss << ((permissions & SVC_PEDESTRIAN) > 0 ? 1 : 0);
219  return oss.str();
220 }
221 
222 
223 int
225  // quoting the navteq manual:
226  // As a general rule, Functional Road Class assignments have no direct
227  // correlation with other road attributes like speed, controlled access, route type, etc.
228  //
229  // we do a simple speed / lane-count mapping anyway
230  // XXX the resulting functional road class layers probably won't be connected as required
231  const int kph = speedInKph(edge->getSpeed());
232  if ((kph) > 100) {
233  return 0;
234  }
235  if ((kph) > 70) {
236  return 1;
237  }
238  if ((kph) > 50) {
239  return (edge->getNumLanes() > 1 ? 2 : 3);
240  }
241  if ((kph) > 30) {
242  return 3;
243  }
244  return 4;
245 }
246 
247 
248 int
250  if ((kph) > 130) {
251  return 1;
252  }
253  if ((kph) > 100) {
254  return 2;
255  }
256  if ((kph) > 90) {
257  return 3;
258  }
259  if ((kph) > 70) {
260  return 4;
261  }
262  if ((kph) > 50) {
263  return 5;
264  }
265  if ((kph) > 30) {
266  return 6;
267  }
268  if ((kph) > 10) {
269  return 7;
270  }
271  return 8;
272 }
273 
274 
275 int
277  if ((kph) > 130) {
278  return 131;
279  }
280  if ((kph) > 100) {
281  return 130;
282  }
283  if ((kph) > 90) {
284  return 100;
285  }
286  if ((kph) > 70) {
287  return 90;
288  }
289  if ((kph) > 50) {
290  return 70;
291  }
292  if ((kph) > 30) {
293  return 50;
294  }
295  if ((kph) > 10) {
296  return 30;
297  }
298  return 10;
299 }
300 
301 
302 unsigned int
303 NWWriter_DlrNavteq::getNavteqLaneCode(const unsigned int numLanes) {
304  const unsigned int code = (numLanes == 1 ? 1 :
305  (numLanes < 4 ? 2 : 3));
306  return numLanes * 10 + code;
307 }
308 
309 
310 SUMOReal
312  PositionVector geom = edge->getGeometry();
315  return geom.length();
316 }
317 
318 
319 void
321  OutputDevice& device = OutputDevice::getDevice(oc.getString("dlr-navteq-output") + "_traffic_signals.txt");
322  writeHeader(device, oc);
323  const GeoConvHelper& gch = GeoConvHelper::getFinal();
324  const bool haveGeo = gch.usingGeoProjection();
325  const SUMOReal geoScale = pow(10.0f, haveGeo ? 5 : 2); // see NIImporter_DlrNavteq::GEO_SCALE
326  device.setPrecision(0);
327  // write format specifier
328  device << "#Traffic signal related to LINK_ID and NODE_ID with location relative to driving direction.\n#column format like pointcollection.\n#DESCRIPTION->LOCATION: 1-rechts von LINK; 2-links von LINK; 3-oberhalb LINK -1-keineAngabe\n#RELATREC_ID\tPOICOL_TYPE\tDESCRIPTION\tLONGITUDE\tLATITUDE\tLINK_ID\n";
329  // write record for every edge incoming to a tls controlled node
330  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
331  NBNode* n = (*i).second;
332  if (n->isTLControlled()) {
333  Position pos = n->getPosition();
334  gch.cartesian2geo(pos);
335  pos.mul(geoScale);
336  const EdgeVector& incoming = n->getIncomingEdges();
337  for (EdgeVector::const_iterator it = incoming.begin(); it != incoming.end(); ++it) {
338  NBEdge* e = *it;
339  device << e->getID() << "\t"
340  << "12\t" // POICOL_TYPE
341  << "LSA;NODEIDS#" << n->getID() << "#;LOCATION#-1#;\t"
342  << pos.x() << "\t"
343  << pos.y() << "\t"
344  << e->getID() << "\n";
345  }
346  }
347  }
348 }
349 
350 
351 /****************************************************************************/
352 
const EdgeVector & getIncomingEdges() const
Returns this node&#39;s incoming edges.
Definition: NBNode.h:240
void close()
Closes the device and removes it from the dictionary.
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
static unsigned int getNavteqLaneCode(const unsigned int numLanes)
get the lane number encoding
static int speedInKph(SUMOReal metersPerSecond)
get edge speed rounded to kmh
static void writeHeader(OutputDevice &device, const OptionsCont &oc)
write header comments (input paramters, date, etc...)
bool isTLControlled() const
Returns whether this node is controlled by any tls.
Definition: NBNode.h:304
static int getRoadClass(NBEdge *edge)
get the navteq road class
int SVCPermissions
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static int getSpeedCategory(int kph)
get the navteq speed class based on the speed in km/h
The representation of a single edge during network building.
Definition: NBEdge.h:70
const std::string & getFullName() const
Definition: OptionsCont.h:622
const SVCPermissions SVCAll
SUMOReal x() const
Returns the x-position.
Definition: Position.h:63
static int getSpeedCategoryUpperBound(int kph)
get the SPEED_LIMIT as defined by elmar (upper bound of speed category)
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
static const std::string UNDEFINED
magic value for undefined stuff
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
const std::string & getID() const
Returns the id.
Definition: Named.h:65
void setPrecision(unsigned int precision=OUTPUT_ACCURACY)
Sets the precison or resets it to default.
void push_front_noDoublePos(const Position &p)
static void writeNodesUnsplitted(const OptionsCont &oc, NBNodeCont &nc, NBEdgeCont &ec)
Writes the nodes_unsplitted file.
const Position & getPosition() const
Returns the position of this node.
Definition: NBNode.h:228
std::map< std::string, NBEdge * >::const_iterator end() const
Returns the pointer to the end of the stored edges.
Definition: NBEdgeCont.h:198
bool usingGeoProjection() const
Returns whether a transformation from geo to metric coordinates will be performed.
static methods for processing the coordinates conversion for the current net
Definition: GeoConvHelper.h:60
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
NBEdgeCont & getEdgeCont()
Returns the edge container.
Definition: NBNetBuilder.h:154
A list of positions.
unsigned int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:345
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:66
static void writeLinksUnsplitted(const OptionsCont &oc, NBEdgeCont &ec)
Writes the links_unsplitted file.
std::map< std::string, NBNode * >::const_iterator end() const
Returns the pointer to the end of the stored nodes.
Definition: NBNodeCont.h:135
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
static void writeNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Writes the network into XML-files (nodes, edges, connections, traffic lights)
std::map< std::string, NBEdge * >::const_iterator begin() const
Returns the pointer to the begin of the stored edges.
Definition: NBEdgeCont.h:190
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition: NBEdge.cpp:2362
static std::string getAllowedTypes(SVCPermissions permissions)
build the ascii-bit-vector for column vehicle_type
SUMOReal length() const
Returns the length.
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:369
NBNodeCont & getNodeCont()
Returns the node container.
Definition: NBNetBuilder.h:162
Instance responsible for building networks.
Definition: NBNetBuilder.h:113
static OutputDevice & getDevice(const std::string &name)
Returns the described OutputDevice.
std::vector< NBEdge * > EdgeVector
Definition: NBCont.h:41
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:521
SUMOReal y() const
Returns the y-position.
Definition: Position.h:68
A storage for options typed value containers)
Definition: OptionsCont.h:108
void mul(SUMOReal val)
Multiplies both positions with the given value.
Definition: Position.h:99
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
static SUMOReal getGraphLength(NBEdge *edge)
get the length of the edge when measured up to the junction center
Represents a single node (junction) during network building.
Definition: NBNode.h:74
static void writeTrafficSignals(const OptionsCont &oc, NBNodeCont &nc)
Writes the traffic_signals file.
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
#define SUMOReal
Definition: config.h:214
void writeConfiguration(std::ostream &os, bool filled, bool complete, bool addComments) const
Writes the configuration.
void push_back_noDoublePos(const Position &p)
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:109
SUMOReal getSpeed() const
Returns the speed allowed on this edge.
Definition: NBEdge.h:429
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:64
std::map< std::string, NBNode * >::const_iterator begin() const
Returns the pointer to the begin of the stored nodes.
Definition: NBNodeCont.h:127
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:361