SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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.sourceforge.net/
12 // Copyright (C) 2001-2012 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>
40 #include <utils/common/ToString.h>
44 #include <netbuild/NBNetBuilder.h>
45 #include <netbuild/NBNode.h>
46 #include <netbuild/NBNodeCont.h>
47 #include <netbuild/NBEdge.h>
48 #include <netbuild/NBEdgeCont.h>
49 #include <netbuild/NBTypeCont.h>
50 #include <netbuild/NBOwnTLDef.h>
52 #include "NILoader.h"
53 #include "NIImporter_DlrNavteq.h"
54 
55 
56 #ifdef CHECK_MEMORY_LEAKS
57 #include <foreign/nvwa/debug_new.h>
58 #endif // CHECK_MEMORY_LEAKS
59 
60 // ---------------------------------------------------------------------------
61 // static members
62 // ---------------------------------------------------------------------------
64 
65 // ===========================================================================
66 // method definitions
67 // ===========================================================================
68 // ---------------------------------------------------------------------------
69 // static methods
70 // ---------------------------------------------------------------------------
71 void
73  // check whether the option is set (properly)
74  if (!oc.isSet("dlr-navteq-prefix")) {
75  return;
76  }
77  // parse file(s)
78  LineReader lr;
79  // load nodes
80  std::map<std::string, PositionVector> myGeoms;
81  PROGRESS_BEGIN_MESSAGE("Loading nodes");
82  std::string file = oc.getString("dlr-navteq-prefix") + "_nodes_unsplitted.txt";
83  NodesHandler handler1(nb.getNodeCont(), file, myGeoms);
84  if (!lr.setFile(file)) {
85  throw ProcessError("The file '" + file + "' could not be opened.");
86  }
87  lr.readAll(handler1);
89 
90  // load street names if given and wished
91  std::map<std::string, std::string> streetNames; // nameID : name
92  if (oc.getBool("output.street-names")) {
93  file = oc.getString("dlr-navteq-prefix") + "_names.txt";
94  if (lr.setFile(file)) {
95  PROGRESS_BEGIN_MESSAGE("Loading Street Names");
96  NamesHandler handler4(file, streetNames);
97  lr.readAll(handler4);
99  } else {
100  WRITE_WARNING("Output will not contain street names because the file '" + file + "' was not found");
101  }
102  }
103 
104  // load edges
105  PROGRESS_BEGIN_MESSAGE("Loading edges");
106  file = oc.getString("dlr-navteq-prefix") + "_links_unsplitted.txt";
107  // parse the file
108  EdgesHandler handler2(nb.getNodeCont(), nb.getEdgeCont(), file, myGeoms, streetNames);
109  if (!lr.setFile(file)) {
110  throw ProcessError("The file '" + file + "' could not be opened.");
111  }
112  lr.readAll(handler2);
115 
116  // load traffic lights if given and not explicitly unwished
117  if (!oc.getBool("tls.discard-loaded")) {
118  file = oc.getString("dlr-navteq-prefix") + "_traffic_signals.txt";
119  if (lr.setFile(file)) {
120  PROGRESS_BEGIN_MESSAGE("Loading traffic lights");
121  TrafficlightsHandler handler3(nb.getNodeCont(), nb.getTLLogicCont(), nb.getEdgeCont(), file);
122  lr.readAll(handler3);
124  }
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 (!NILoader::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), myEdgeCont(ec), myGeoms(geoms), myStreetNames(streetNames) {
210  UNUSED_PARAMETER(file);
211 }
212 
213 
215 
216 
217 bool
218 NIImporter_DlrNavteq::EdgesHandler::report(const std::string& result) {
219 // 0: LINK_ID NODE_ID_FROM NODE_ID_TO BETWEEN_NODE_ID
220 // 4: length vehicle_type form_of_way brunnel_type
221 // 7: street_type speed_category number_of_lanes average_speed
222 // 10: NAME_ID1 NAME_ID2 housenumbers_right housenumbers_left
223 // ZIP_CODE AREA_ID SUBAREA_ID through_traffic special_restrictions
224 // extended_number_of_lanes isRamp (these two only exist in networks extracted since 05/2009)
225 // connection (this may be omitted)
226 
227  if (result[0] == '#') {
228  return true;
229  }
230  std::string id, fromID, toID, interID;
231  SUMOReal length;
232  SUMOReal speed = (SUMOReal) 30.0 / (SUMOReal) 3.6;
233  int nolanes = 1;
234  int priority;
235  int form_of_way;
236  // parse
238  // id
239  id = st.next();
240  // from node id
241  fromID = st.next();
242  // to node id
243  toID = st.next();
244  // intermediate node id
245  interID = st.next();
246  // length
247  try {
248  length = TplConvert::_2SUMOReal(st.next().c_str());
249  } catch (NumberFormatException&) {
250  throw ProcessError("Non-numerical value for an edge's length occured (edge '" + id + "'.");
251  }
252  // vehicle_type
253  std::string veh_type = st.next();
254  // form_of_way
255  try {
256  form_of_way = TplConvert::_2int(st.next().c_str());
257  } catch (NumberFormatException&) {
258  throw ProcessError("Non-numerical value for an edge's form_of_way occured (edge '" + id + "'.");
259  }
260  // brunnel_type
261  std::string brunnel_type = st.next();
262  // street_type used for priority
263  try {
264  priority = -TplConvert::_2int(st.next().c_str());
265  } catch (NumberFormatException&) {
266  throw ProcessError("Non-numerical value for an edge's street_type occured (edge '" + id + "'.");
267  }
268  // modify priority using form_of_way
269  if (form_of_way == 11) {
270  priority -= 1; // frontage road, very often with lowered curb
271  } else if (form_of_way > 11) {
272  priority -= 2; // parking/service access assume lowered curb
273  }
274  speed = NINavTeqHelper::getSpeed(id, st.next());
275  // number of lanes
276  nolanes = NINavTeqHelper::getLaneNumber(id, st.next(), speed);
277  // average_speed (reportedly this is simply the speed from speed_category minus 10km/h)
278  std::string average_speed = st.next();
279  // regional street name id
280  std::string nameID_regional = st.next();
281  // local street name id
282  std::string nameID_local = st.next();
283  std::string streetName = getStreetNameFromIDs(nameID_regional, nameID_local);
284  std::vector<std::string> theRest = st.getVector();
285  bool connection = (theRest.size() == 8) && (theRest[7] == "1");
286  if (theRest.size() > 8) {
287  // post 05/2009 network
288  if (theRest[8] != "-1") {
289  try {
290  nolanes = TplConvert::_2int(theRest[8].c_str());
291  } catch (NumberFormatException&) {
292  throw ProcessError("Non-numerical value for the extended number of lanes (edge '" + id + "'.");
293  }
294  }
295  connection = (theRest.size() == 10) && (theRest[9] == "1");
296  }
297  // try to get the nodes
298  NBNode* from = myNodeCont.retrieve(fromID);
299  NBNode* to = myNodeCont.retrieve(toID);
300  if (from == 0) {
301  throw ProcessError("The from-node '" + fromID + "' of edge '" + id + "' could not be found");
302  }
303  if (to == 0) {
304  throw ProcessError("The to-node '" + toID + "' of edge '" + id + "' could not be found");
305  }
306  // build the edge
307  NBEdge* e = 0;
308  if (interID == "-1") {
309  e = new NBEdge(id, from, to, "", speed, nolanes, priority,
311  } else {
312  PositionVector geoms = myGeoms[interID];
313  if (connection) {
314  geoms = geoms.reverse();
315  }
316  geoms.push_front(from->getPosition());
317  geoms.push_back(to->getPosition());
318  e = new NBEdge(id, from, to, "", speed, nolanes, priority,
320  }
321  // add vehicle type information to the edge
322  NINavTeqHelper::addVehicleClasses(*e, veh_type);
323  // permission modifications based on form_of_way
324  if (form_of_way == 14) { // pedestrian area (fussgaengerzone)
325  // unfortunately, the veh_type string is misleading in this case
327  }
328  // insert the edge to the network
329  if (!myEdgeCont.insert(e)) {
330  delete e;
331  throw ProcessError("Could not add edge '" + id + "'.");
332  }
333  return true;
334 }
335 
336 
337 std::string
339  const std::string& regionalID, const std::string& localID) const {
340  std::string result = "";
341  bool hadRegional = false;
342  if (myStreetNames.count(regionalID) > 0) {
343  hadRegional = true;
344  result += myStreetNames[regionalID];
345  }
346  if (myStreetNames.count(localID) > 0) {
347  if (hadRegional) {
348  result += " / ";
349  }
350  result += myStreetNames[localID];
351  }
352  return result;
353 }
354 
355 // ---------------------------------------------------------------------------
356 // definitions of NIImporter_DlrNavteq::TrafficlightsHandler-methods
357 // ---------------------------------------------------------------------------
360  NBEdgeCont& ne,
361  const std::string& file) :
362  myNodeCont(nc),
363  myTLLogicCont(tlc),
364  myEdgeCont(ne) {
365  UNUSED_PARAMETER(file);
366 }
367 
368 
370 
371 
372 bool
374 // #ID POICOL-TYPE DESCRIPTION LONGITUDE LATITUDE NAVTEQ_LINK_ID NODEID
375 
376  if (result[0] == '#') {
377  return true;
378  }
380  const std::string edgeID = st.get(5);
381  NBEdge* edge = myEdgeCont.retrieve(edgeID);
382  if (edge == 0) {
383  WRITE_WARNING("The traffic light edge '" + edgeID + "' could not be found");
384  } else {
385  NBNode* node = edge->getToNode();
386  if (node->getType() != NODETYPE_TRAFFIC_LIGHT) {
387  node->reinit(node->getPosition(), NODETYPE_TRAFFIC_LIGHT);
388  // @note actually we could use the navteq node ID here
389  NBTrafficLightDefinition* tlDef = new NBOwnTLDef(node->getID(), node, 0);
390  if (!myTLLogicCont.insert(tlDef)) {
391  // actually, nothing should fail here
392  delete tlDef;
393  throw ProcessError("Could not allocate tls for '" + node->getID() + "'.");
394  }
395  }
396  }
397  return true;
398 }
399 
400 
401 // ---------------------------------------------------------------------------
402 // definitions of NIImporter_DlrNavteq::NamesHandler-methods
403 // ---------------------------------------------------------------------------
405  const std::string& file, std::map<std::string, std::string>& streetNames) :
406  myStreetNames(streetNames) {
407  UNUSED_PARAMETER(file);
408 }
409 
410 
412 
413 
414 bool
415 NIImporter_DlrNavteq::NamesHandler::report(const std::string& result) {
416 // # NAME_ID Name
417  if (result[0] == '#') {
418  return true;
419  }
421  if (st.size() == 1) {
422  return true; // one line with the number of data containing lines in it
423  }
424  assert(st.size() >= 2);
425  const std::string id = st.next();
426  myStreetNames[id] = joinToString(st.getVector(), " ");
427  return true;
428 }
429 /****************************************************************************/