SUMO - Simulation of Urban MObility
NIImporter_DlrNavteq.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // Importer for networks stored in Elmar's format
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
12 // Copyright (C) 2001-2015 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 
33 #include <string>
34 #include <sstream>
35 #include <limits>
41 #include <utils/common/ToString.h>
45 #include <netbuild/NBNetBuilder.h>
46 #include <netbuild/NBNode.h>
47 #include <netbuild/NBNodeCont.h>
48 #include <netbuild/NBEdge.h>
49 #include <netbuild/NBEdgeCont.h>
50 #include <netbuild/NBTypeCont.h>
51 #include <netbuild/NBOwnTLDef.h>
53 #include "NILoader.h"
54 #include "NIImporter_DlrNavteq.h"
55 
56 
57 #ifdef CHECK_MEMORY_LEAKS
58 #include <foreign/nvwa/debug_new.h>
59 #endif // CHECK_MEMORY_LEAKS
60 
61 // ---------------------------------------------------------------------------
62 // static members
63 // ---------------------------------------------------------------------------
66 
67 // ===========================================================================
68 // method definitions
69 // ===========================================================================
70 // ---------------------------------------------------------------------------
71 // static methods
72 // ---------------------------------------------------------------------------
73 void
75  // check whether the option is set (properly)
76  if (!oc.isSet("dlr-navteq-prefix")) {
77  return;
78  }
79  // parse file(s)
80  LineReader lr;
81  // load nodes
82  std::map<std::string, PositionVector> myGeoms;
83  PROGRESS_BEGIN_MESSAGE("Loading nodes");
84  std::string file = oc.getString("dlr-navteq-prefix") + "_nodes_unsplitted.txt";
85  NodesHandler handler1(nb.getNodeCont(), file, myGeoms);
86  if (!lr.setFile(file)) {
87  throw ProcessError("The file '" + file + "' could not be opened.");
88  }
89  lr.readAll(handler1);
91 
92  // load street names if given and wished
93  std::map<std::string, std::string> streetNames; // nameID : name
94  if (oc.getBool("output.street-names")) {
95  file = oc.getString("dlr-navteq-prefix") + "_names.txt";
96  if (lr.setFile(file)) {
97  PROGRESS_BEGIN_MESSAGE("Loading Street Names");
98  NamesHandler handler4(file, streetNames);
99  lr.readAll(handler4);
101  } else {
102  WRITE_WARNING("Output will not contain street names because the file '" + file + "' was not found");
103  }
104  }
105 
106  // load edges
107  PROGRESS_BEGIN_MESSAGE("Loading edges");
108  file = oc.getString("dlr-navteq-prefix") + "_links_unsplitted.txt";
109  // parse the file
110  EdgesHandler handler2(nb.getNodeCont(), nb.getEdgeCont(), file, myGeoms, streetNames);
111  if (!lr.setFile(file)) {
112  throw ProcessError("The file '" + file + "' could not be opened.");
113  }
114  lr.readAll(handler2);
117 
118  // load traffic lights if given
119  file = oc.getString("dlr-navteq-prefix") + "_traffic_signals.txt";
120  if (lr.setFile(file)) {
121  PROGRESS_BEGIN_MESSAGE("Loading traffic lights");
122  TrafficlightsHandler handler3(nb.getNodeCont(), nb.getTLLogicCont(), nb.getEdgeCont(), file);
123  lr.readAll(handler3);
125  }
126 }
127 
128 
129 // ---------------------------------------------------------------------------
130 // definitions of NIImporter_DlrNavteq::NodesHandler-methods
131 // ---------------------------------------------------------------------------
133  const std::string& file,
134  std::map<std::string, PositionVector>& geoms)
135  : myNodeCont(nc), myGeoms(geoms) {
136  UNUSED_PARAMETER(file);
137 }
138 
139 
141 
142 
143 bool
144 NIImporter_DlrNavteq::NodesHandler::report(const std::string& result) {
145  if (result[0] == '#') {
146  return true;
147  }
148  std::string id;
149  double x, y;
150  int no_geoms, intermediate;
151  // parse
152  std::istringstream stream(result);
153  // id
154  stream >> id;
155  if (stream.fail()) {
156  throw ProcessError("Something is wrong with the following data line\n" + result);
157  }
158  // intermediate?
159  stream >> intermediate;
160  if (stream.fail()) {
161  if (myNodeCont.size() == 0) { // be generous with extra data at beginning of file
162  return true;
163  }
164  throw ProcessError("Non-numerical value for intermediate status in node " + id + ".");
165  }
166  // number of geometrical information
167  stream >> no_geoms;
168  if (stream.fail()) {
169  throw ProcessError("Non-numerical value for number of geometries in node " + id + ".");
170  }
171  // geometrical information
172  PositionVector geoms;
173  for (int i = 0; i < no_geoms; i++) {
174  stream >> x;
175  if (stream.fail()) {
176  throw ProcessError("Non-numerical value for x-position in node " + id + ".");
177  }
178  stream >> y;
179  if (stream.fail()) {
180  throw ProcessError("Non-numerical value for y-position in node " + id + ".");
181  }
182  Position pos(x, y);
183  if (!NBNetBuilder::transformCoordinates(pos, true)) {
184  throw ProcessError("Unable to project coordinates for node " + id + ".");
185  }
186  geoms.push_back(pos);
187  }
188 
189  if (intermediate == 0) {
190  NBNode* n = new NBNode(id, geoms[0]);
191  if (!myNodeCont.insert(n)) {
192  delete n;
193  throw ProcessError("Could not add node '" + id + "'.");
194  }
195  } else {
196  myGeoms[id] = geoms;
197  }
198  return true;
199 }
200 
201 
202 // ---------------------------------------------------------------------------
203 // definitions of NIImporter_DlrNavteq::EdgesHandler-methods
204 // ---------------------------------------------------------------------------
206  const std::string& file,
207  std::map<std::string, PositionVector>& geoms,
208  std::map<std::string, std::string>& streetNames):
209  myNodeCont(nc),
210  myEdgeCont(ec),
211  myGeoms(geoms),
212  myStreetNames(streetNames),
213  myVersion(0),
214  myFile(file)
215 { }
216 
217 
219 
220 
221 bool
222 NIImporter_DlrNavteq::EdgesHandler::report(const std::string& result) {
223  // parse version number from first comment line and initialize column definitions
224  if (result[0] == '#') {
225  if (!myColumns.empty()) {
226  return true;
227  }
228  const std::string marker = "Extraction version: V";
229  size_t vStart = result.find(marker);
230  if (vStart == std::string::npos) {
231  return true;
232  }
233  vStart += marker.size();
234  const size_t vEnd = result.find(" ", vStart);
235  try {
236  myVersion = TplConvert::_2SUMOReal(result.substr(vStart, vEnd - vStart).c_str());
237  if (myVersion < 0) {
238  throw ProcessError("Invalid version number '" + toString(myVersion) + "' in file '" + myFile + "'.");
239  }
240  // init columns
241  const size_t NUM_COLUMNS = 25; // @note arrays must match this size!
242  const int MC = MISSING_COLUMN;
243  if (myVersion < 3) {
244  const int columns[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, MC, 12, 13, 14, 15, 16, 17, 18, 19, 20, MC, MC, -21};
245  myColumns = std::vector<int>(columns, columns + NUM_COLUMNS);
246  } else if (myVersion < 6) {
247  const int columns[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, MC, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, -23};
248  myColumns = std::vector<int>(columns, columns + NUM_COLUMNS);
249  } else {
250  const int columns[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};
251  myColumns = std::vector<int>(columns, columns + NUM_COLUMNS);
252  }
253  } catch (NumberFormatException&) {
254  throw ProcessError("Non-numerical value for version string in file '" + myFile + "'.");
255  }
256  return true;
257  }
258  if (myColumns.empty()) {
259  throw ProcessError("Missing version string in file '" + myFile + "'.");
260  }
261  // interpret link attributes
263  const std::string id = getColumn(st, LINK_ID);
264  // form of way (for priority and permissions)
265  int form_of_way;
266  try {
267  form_of_way = TplConvert::_2int(getColumn(st, FORM_OF_WAY).c_str());
268  } catch (NumberFormatException&) {
269  throw ProcessError("Non-numerical value for form_of_way of link '" + id + "'.");
270  }
271  // priority based on street_type / frc
272  int priority;
273  try {
274  priority = -TplConvert::_2int(getColumn(st, FUNCTIONAL_ROAD_CLASS).c_str());
275  // lower priority using form_of_way
276  if (form_of_way == 11) {
277  priority -= 1; // frontage road, very often with lowered curb
278  } else if (form_of_way > 11) {
279  priority -= 2; // parking/service access assume lowered curb
280  }
281  } catch (NumberFormatException&) {
282  throw ProcessError("Non-numerical value for street_type of link '" + id + "').");
283  }
284  // street name
285  std::string streetName = getStreetNameFromIDs(
288  // try to get the nodes
289  const std::string fromID = getColumn(st, NODE_ID_FROM);
290  const std::string toID = getColumn(st, NODE_ID_TO);
291  NBNode* from = myNodeCont.retrieve(fromID);
292  NBNode* to = myNodeCont.retrieve(toID);
293  if (from == 0) {
294  throw ProcessError("The from-node '" + fromID + "' of link '" + id + "' could not be found");
295  }
296  if (to == 0) {
297  throw ProcessError("The to-node '" + toID + "' of link '" + id + "' could not be found");
298  }
299  // speed
300  SUMOReal speed;
301  try {
302  speed = TplConvert::_2int(getColumn(st, SPEED_RESTRICTION, "-1").c_str()) / 3.6;
303  } catch (NumberFormatException) {
304  throw ProcessError("Non-numerical value for the SPEED_RESTRICTION of link '" + id + "'.");
305  }
306  if (speed < 0) {
307  // speed category as fallback
309  }
310  // number of lanes
311  int numLanes;
312  try {
313  // EXTENDED_NUMBER_OF_LANES is prefered but may not be defined
314  numLanes = TplConvert::_2int(getColumn(st, EXTENDED_NUMBER_OF_LANES, "-1").c_str());
315  if (numLanes == -1) {
316  numLanes = NINavTeqHelper::getLaneNumber(id, getColumn(st, NUMBER_OF_LANES), speed);
317  }
318  } catch (NumberFormatException&) {
319  throw ProcessError("Non-numerical value for the number of lanes of link '" + id + "'.");
320  }
321  // build the edge
322  NBEdge* e = 0;
323  const std::string interID = getColumn(st, BETWEEN_NODE_ID);
324  if (interID == "-1") {
325  e = new NBEdge(id, from, to, "", speed, numLanes, priority,
327  } else {
328  PositionVector geoms = myGeoms[interID];
329  if (getColumn(st, CONNECTION, "0") == "1") {
330  geoms = geoms.reverse();
331  }
332  geoms.insert(geoms.begin(), from->getPosition());
333  geoms.push_back(to->getPosition());
334  e = new NBEdge(id, from, to, "", speed, numLanes, priority,
336  }
337  // add vehicle type information to the edge
338  if (myVersion < 6.0) {
340  } else {
342  }
343  // permission modifications based on form_of_way
344  if (form_of_way == 14) { // pedestrian area (fussgaengerzone)
345  // unfortunately, the veh_type string is misleading in this case
347  }
348  // insert the edge to the network
349  if (!myEdgeCont.insert(e)) {
350  delete e;
351  throw ProcessError("Could not add edge '" + id + "'.");
352  }
353  return true;
354 }
355 
356 
357 std::string
358 NIImporter_DlrNavteq::EdgesHandler::getColumn(const StringTokenizer& st, ColumnName name, const std::string fallback) {
359  assert(!myColumns.empty());
360  if (myColumns[name] == MISSING_COLUMN) {
361  if (fallback == "") {
362  throw ProcessError("Missing column " + toString(name) + ".");
363  } else {
364  return fallback;
365  }
366  } else if (myColumns[name] >= 0) {
367  return st.get((size_t)(myColumns[name]));
368  } else {
369  // negative column number implies an optional column
370  if ((int) st.size() <= -myColumns[name]) {
371  // the column is not present
372  if (fallback == "") {
373  throw ProcessError("Missing optional column " + toString(name) + " without default value.");
374  } else {
375  return fallback;
376  }
377  } else {
378  return st.get((size_t)(-myColumns[name]));
379  }
380  }
381 }
382 
383 
384 std::string
386  const std::string& regionalID, const std::string& localID) const {
387  std::string result = "";
388  bool hadRegional = false;
389  if (myStreetNames.count(regionalID) > 0) {
390  hadRegional = true;
391  result += myStreetNames[regionalID];
392  }
393  if (myStreetNames.count(localID) > 0) {
394  if (hadRegional) {
395  result += " / ";
396  }
397  result += myStreetNames[localID];
398  }
399  return result;
400 }
401 
402 // ---------------------------------------------------------------------------
403 // definitions of NIImporter_DlrNavteq::TrafficlightsHandler-methods
404 // ---------------------------------------------------------------------------
407  NBEdgeCont& ne,
408  const std::string& file) :
409  myNodeCont(nc),
410  myTLLogicCont(tlc),
411  myEdgeCont(ne) {
412  UNUSED_PARAMETER(file);
413 }
414 
415 
417 
418 
419 bool
421 // #ID POICOL-TYPE DESCRIPTION LONGITUDE LATITUDE NAVTEQ_LINK_ID NODEID
422 
423  if (result[0] == '#') {
424  return true;
425  }
427  const std::string edgeID = st.get(5);
428  NBEdge* edge = myEdgeCont.retrieve(edgeID);
429  if (edge == 0) {
430  WRITE_WARNING("The traffic light edge '" + edgeID + "' could not be found");
431  } else {
432  NBNode* node = edge->getToNode();
433  if (node->getType() != NODETYPE_TRAFFIC_LIGHT) {
434  node->reinit(node->getPosition(), NODETYPE_TRAFFIC_LIGHT);
435  // @note. There may be additional information somewhere in the GDF files about traffic light type ...
437  // @note actually we could use the navteq node ID here
438  NBTrafficLightDefinition* tlDef = new NBOwnTLDef(node->getID(), node, 0, type);
439  if (!myTLLogicCont.insert(tlDef)) {
440  // actually, nothing should fail here
441  delete tlDef;
442  throw ProcessError("Could not allocate tls for '" + node->getID() + "'.");
443  }
444  }
445  }
446  return true;
447 }
448 
449 
450 // ---------------------------------------------------------------------------
451 // definitions of NIImporter_DlrNavteq::NamesHandler-methods
452 // ---------------------------------------------------------------------------
454  const std::string& file, std::map<std::string, std::string>& streetNames) :
455  myStreetNames(streetNames) {
456  UNUSED_PARAMETER(file);
457 }
458 
459 
461 
462 
463 bool
464 NIImporter_DlrNavteq::NamesHandler::report(const std::string& result) {
465 // # NAME_ID Name
466  if (result[0] == '#') {
467  return true;
468  }
470  if (st.size() == 1) {
471  return true; // one line with the number of data containing lines in it
472  }
473  assert(st.size() >= 2);
474  const std::string id = st.next();
475  myStreetNames[id] = joinToString(st.getVector(), " ");
476  return true;
477 }
478 /****************************************************************************/
bool report(const std::string &result)
Parsing method.
NBNodeCont & myNodeCont
The node container to get the referenced nodes from.
static const SUMOReal UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:201
bool report(const std::string &result)
Parsing method.
std::string next()
static bool transformCoordinates(Position &from, bool includeInBoundary=true, GeoConvHelper *from_srs=0)
transforms loaded coordinates handles projections, offsets (using GeoConvHelper) and import of height...
std::map< std::string, std::string > & myStreetNames
Previously read streat names (non-const because operate[] is more convenient)
static SUMOReal _2SUMOReal(const E *const data)
Definition: TplConvert.h:242
static const int WHITECHARS
Importer of street names in DLRNavteq&#39;s (aka elmar) format.
Importer of nodes stored in unsplit elmar format.
A container for traffic light definitions and built programs.
Retrieves a file linewise and reports the lines to a handler.
Definition: LineReader.h:58
void reinit(const Position &position, SumoXMLNodeType type, bool updateEdgeGeometries=false)
Resets initial values.
Definition: NBNode.cpp:264
bool report(const std::string &result)
Parsing method.
NodesHandler(NBNodeCont &nc, const std::string &file, std::map< std::string, PositionVector > &geoms)
Constructor.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
The representation of a single edge during network building.
Definition: NBEdge.h:70
static void loadNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Loads content of the optionally given dlr-navteq (aka Elmar-fomat) folder.
The base class for traffic light logic definitions.
static void addVehicleClasses(NBEdge &e, const std::string &classS)
Adds vehicle classes parsing the given list of allowed vehicles.
bool setFile(const std::string &file)
Reinitialises the reader for reading from the given file.
Definition: LineReader.cpp:189
NBEdgeCont & myEdgeCont
The edge container to store loaded edges into.
std::map< std::string, PositionVector > & myGeoms
Previously read edge geometries (manipulated during use)
static const SUMOReal UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:203
std::string get(size_t pos) const
Importer of traffic lights stored in DLRNavteq&#39;s (aka elmar) format.
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:39
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:69
PositionVector reverse() const
Importer of edges stored in unsplit elmar format.
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
unsigned int size() const
Returns the number of known nodes.
Definition: NBNodeCont.h:273
const Position & getPosition() const
Returns the position of this node.
Definition: NBNode.h:228
void readAll(LineHandler &lh)
Reads the whole file linewise, reporting every line to the given LineHandler.
Definition: LineReader.cpp:70
#define max(a, b)
Definition: polyfonts.c:65
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
Definition: NBEdgeCont.cpp:161
NamesHandler(const std::string &file, std::map< std::string, std::string > &streetNames)
Constructor.
static StringBijection< TrafficLightType > TrafficLightTypes
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.
SumoXMLNodeType getType() const
Returns the type of this node.
Definition: NBNode.h:265
std::map< std::string, PositionVector > & myGeoms
A container for parsed geometries.
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:66
const std::string myFile
the file being parsed
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:202
size_t size() const
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
vehicle is a passenger car (a "normal" car)
static unsigned int getLaneNumber(const std::string &id, const std::string &laneNoS, SUMOReal speed)
Returns the lane number evaluating the given Navteq-description.
static SUMOReal getSpeed(const std::string &id, const std::string &speedClassS)
Returns the speed evaluating the given Navteq-description.
SUMOReal myVersion
version number of current file
std::vector< std::string > getVector()
std::string getStreetNameFromIDs(const std::string &regionalID, const std::string &localID) const
build the street name for the given ids
NBEdgeCont & myEdgeCont
The edge container to get the referenced edges from.
static void addVehicleClassesV6(NBEdge &e, const std::string &classS)
same as addVehicleClasses but for version 6+
static int _2int(const E *const data)
Definition: TplConvert.h:114
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:369
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:246
EdgesHandler(NBNodeCont &nc, NBEdgeCont &ec, const std::string &file, std::map< std::string, PositionVector > &geoms, std::map< std::string, std::string > &streetNames)
Constructor.
NBNodeCont & getNodeCont()
Returns the node container.
Definition: NBNetBuilder.h:162
Instance responsible for building networks.
Definition: NBNetBuilder.h:113
A storage for options typed value containers)
Definition: OptionsCont.h:108
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
Definition: NBNodeCont.cpp:80
NBTrafficLightLogicCont & getTLLogicCont()
Returns the traffic light logics container.
Definition: NBNetBuilder.h:178
std::map< std::string, std::string > & myStreetNames
The container for storing read names.
NBTrafficLightLogicCont & myTLLogicCont
The traffic lights container to add built tls to.
Represents a single node (junction) during network building.
Definition: NBNode.h:74
T get(const std::string &str) const
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:159
static const int GEO_SCALE
scaling factor for geo coordinates (DLRNavteq format uses this to increase floating point precisions)...
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
void recheckLaneSpread()
Rechecks whether the lane spread is proper.
Definition: NBEdgeCont.cpp:727
#define SUMOReal
Definition: config.h:214
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:109
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:64
TrafficlightsHandler(NBNodeCont &nc, NBTrafficLightLogicCont &tlc, NBEdgeCont &ne, const std::string &file)
Constructor.
#define PROGRESS_DONE_MESSAGE()
Definition: MsgHandler.h:203
A traffic light logics which must be computed (only nodes/edges are given)
Definition: NBOwnTLDef.h:54
std::vector< int > myColumns
the version number of the edge file being parsed
void disallowVehicleClass(int lane, SUMOVehicleClass vclass)
set disallowed class for the given lane or for all lanes if -1 is given
Definition: NBEdge.cpp:2237
TrafficLightType
std::string getColumn(const StringTokenizer &st, ColumnName name, const std::string fallback="")
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
bool report(const std::string &result)
Parsing method.