SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NWWriter_DlrNavteq.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // Exporter writing networks using DlrNavteq (Elmar) format
8 /****************************************************************************/
9 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
10 // Copyright (C) 2001-2013 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 #include <algorithm>
31 #include <ctime>
32 #include <cmath>
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_DlrNavteq.h"
46 
47 #ifdef CHECK_MEMORY_LEAKS
48 #include <foreign/nvwa/debug_new.h>
49 #endif // CHECK_MEMORY_LEAKS
50 
51 
52 // ---------------------------------------------------------------------------
53 // static members
54 // ---------------------------------------------------------------------------
55 const std::string NWWriter_DlrNavteq::UNDEFINED("-1");
56 
57 // ---------------------------------------------------------------------------
58 // static methods
59 // ---------------------------------------------------------------------------
60 void
62  // check whether a matsim-file shall be generated
63  if (!oc.isSet("dlr-navteq-output")) {
64  return;
65  }
68 }
69 
70 
72  time_t rawtime;
73  time(&rawtime);
74  char buffer [80];
75  strftime(buffer, 80, "on %c", localtime(&rawtime));
76  device << "# Generated " << buffer << " by " << oc.getFullName() << "\n";
77  device << "# Format matches Extraction version: V6.0 \n";
78  std::stringstream tmp;
79  oc.writeConfiguration(tmp, true, false, false);
80  tmp.seekg(std::ios_base::beg);
81  std::string line;
82  while (!tmp.eof()) {
83  std::getline(tmp, line);
84  device << "# " << line << "\n";
85  }
86  device << "#\n";
87 }
88 
89 void
91  // For "real" nodes we simply use the node id.
92  // For internal nodes (geometry vectors describing edge geometry in the parlance of this format)
93  // we use the id of the edge and do not bother with
94  // compression (each direction gets its own internal node).
95  // XXX add option for generating numerical ids in case the input network has string ids and the target process needs integers
96  OutputDevice& device = OutputDevice::getDevice(oc.getString("dlr-navteq-output") + "_nodes_unsplitted.txt");
97  writeHeader(device, oc);
99  const bool haveGeo = gch.usingGeoProjection();
100  const SUMOReal geoScale = pow(10.0f, haveGeo ? 5 : 2); // see NIImporter_DlrNavteq::GEO_SCALE
101  device.setPrecision(0);
102  if (!haveGeo) {
103  WRITE_WARNING("DlrNavteq node data will be written in (floating point) cartesian coordinates");
104  }
105  // write format specifier
106  device << "# NODE_ID\tIS_BETWEEN_NODE\tamount_of_geocoordinates\tx1\ty1\t[x2 y2 ... xn yn]\n";
107  // write normal nodes
108  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
109  NBNode* n = (*i).second;
110  Position pos = n->getPosition();
111  gch.cartesian2geo(pos);
112  pos.mul(geoScale);
113  device << n->getID() << "\t0\t1\t" << pos.x() << "\t" << pos.y() << "\n";
114  }
115  // write "internal" nodes
116  for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) {
117  NBEdge* e = (*i).second;
118  const PositionVector& geom = e->getGeometry();
119  if (geom.size() > 2) {
120  if (e->getID() == UNDEFINED) {
121  WRITE_WARNING("Edge id '" + UNDEFINED +
122  "' clashes with the magic value for NO_BETWEEN_NODE. Internal geometry for this edge will be lost.");
123  }
124  device << e->getID() << "\t1\t" << geom.size() - 2;
125  for (size_t ii = 1; ii < geom.size() - 1; ++ii) {
126  Position pos = geom[(int)ii];
127  gch.cartesian2geo(pos);
128  pos.mul(geoScale);
129  device << "\t" << pos.x() << "\t" << pos.y();
130  }
131  device << "\n";
132  }
133  }
134  device.close();
135 }
136 
137 
138 void
140  OutputDevice& device = OutputDevice::getDevice(oc.getString("dlr-navteq-output") + "_links_unsplitted.txt");
141  writeHeader(device, oc);
142  // write format specifier
143  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";
144  // write edges
145  for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) {
146  NBEdge* e = (*i).second;
147  const int kph = speedInKph(e->getSpeed());
148  const std::string& betweenNodeID = (e->getGeometry().size() > 2) ? e->getID() : UNDEFINED;
149  device << e->getID() << "\t"
150  << e->getFromNode()->getID() << "\t"
151  << e->getToNode()->getID() << "\t"
152  << betweenNodeID << "\t"
153  << getGraphLength(e) << "\t"
154  << getAllowedTypes(e->getPermissions()) << "\t"
155  << "3\t" // Speed Category 1-8 XXX refine this
156  << UNDEFINED << "\t" // no special brunnel type (we don't know yet)
157  << getRoadClass(e) << "\t"
158  << getSpeedCategory(kph) << "\t"
159  << getNavteqLaneCode(e->getNumLanes()) << "\t"
160  << getSpeedCategoryUpperBound(kph) << "\t"
161  << kph << "\t"
162  << UNDEFINED << "\t" // NAME_ID1_REGIONAL XXX
163  << UNDEFINED << "\t" // NAME_ID2_LOCAL XXX
164  << UNDEFINED << "\t" // housenumbers_right
165  << UNDEFINED << "\t" // housenumbers_left
166  << UNDEFINED << "\t" // ZIP_CODE
167  << UNDEFINED << "\t" // AREA_ID
168  << UNDEFINED << "\t" // SUBAREA_ID
169  << "1\t" // through_traffic (allowed)
170  << UNDEFINED << "\t" // special_restrictions
171  << UNDEFINED << "\t" // extended_number_of_lanes
172  << UNDEFINED << "\t" // isRamp
173  << "0\t" // connection (between nodes always in order)
174  << "\n";
175  }
176 }
177 
178 
179 std::string
181  if (permissions == SVCFreeForAll) {
182  return "100000000000";
183  }
184  std::ostringstream oss;
185  oss << "0";
186  oss << ((permissions & SVC_PASSENGER) > 0 ? 1 : 0);
187  oss << ((permissions & SVC_PASSENGER) > 0 ? 1 : 0); // residential
188  oss << ((permissions & SVC_HOV) > 0 ? 1 : 0);
189  oss << ((permissions & SVC_PUBLIC_EMERGENCY) > 0 ? 1 : 0);
190  oss << ((permissions & SVC_TAXI) > 0 ? 1 : 0);
191  oss << ((permissions & (SVC_PUBLIC_TRANSPORT | SVC_BUS)) > 0 ? 1 : 0);
192  oss << ((permissions & SVC_DELIVERY) > 0 ? 1 : 0);
193  oss << ((permissions & SVC_TRANSPORT) > 0 ? 1 : 0);
194  oss << ((permissions & SVC_MOTORCYCLE) > 0 ? 1 : 0);
195  oss << ((permissions & SVC_BICYCLE) > 0 ? 1 : 0);
196  oss << ((permissions & SVC_PEDESTRIAN) > 0 ? 1 : 0);
197  return oss.str();
198 }
199 
200 
201 int
203  // quoting the navteq manual:
204  // As a general rule, Functional Road Class assignments have no direct
205  // correlation with other road attributes like speed, controlled access, route type, etc.
206  //
207  // we do a simple speed / lane-count mapping anyway
208  // XXX the resulting functional road class layers probably won't be connected as required
209  const int kph = speedInKph(edge->getSpeed());
210  if ((kph) > 100) {
211  return 0;
212  }
213  if ((kph) > 70) {
214  return 1;
215  }
216  if ((kph) > 50) {
217  return (edge->getNumLanes() > 1 ? 2 : 3);
218  }
219  if ((kph) > 30) {
220  return 3;
221  }
222  return 4;
223 }
224 
225 
226 int
228  if ((kph) > 130) {
229  return 1;
230  }
231  if ((kph) > 100) {
232  return 2;
233  }
234  if ((kph) > 90) {
235  return 3;
236  }
237  if ((kph) > 70) {
238  return 4;
239  }
240  if ((kph) > 50) {
241  return 5;
242  }
243  if ((kph) > 30) {
244  return 6;
245  }
246  if ((kph) > 10) {
247  return 7;
248  }
249  return 8;
250 }
251 
252 
253 int
255  if ((kph) > 130) {
256  return 131;
257  }
258  if ((kph) > 100) {
259  return 130;
260  }
261  if ((kph) > 90) {
262  return 100;
263  }
264  if ((kph) > 70) {
265  return 90;
266  }
267  if ((kph) > 50) {
268  return 70;
269  }
270  if ((kph) > 30) {
271  return 50;
272  }
273  if ((kph) > 10) {
274  return 30;
275  }
276  return 10;
277 }
278 
279 
280 unsigned int
281 NWWriter_DlrNavteq::getNavteqLaneCode(const unsigned int numLanes) {
282  const unsigned int code = (numLanes == 1 ? 1 :
283  (numLanes < 4 ? 2 : 3));
284  return numLanes * 10 + code;
285 }
286 
287 
288 SUMOReal
290  PositionVector geom = edge->getGeometry();
293  return geom.length();
294 }
295 /****************************************************************************/
296