SUMO - Simulation of Urban MObility
NIImporter_DlrNavteq.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
17 // Importer for networks stored in Elmar's format
18 /****************************************************************************/
19 
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25 
26 #include <string>
27 #include <sstream>
28 #include <limits>
34 #include <utils/common/ToString.h>
39 #include <netbuild/NBNetBuilder.h>
40 #include <netbuild/NBNode.h>
41 #include <netbuild/NBNodeCont.h>
42 #include <netbuild/NBEdge.h>
43 #include <netbuild/NBEdgeCont.h>
44 #include <netbuild/NBTypeCont.h>
45 #include <netbuild/NBOwnTLDef.h>
47 #include "NILoader.h"
48 #include "NIImporter_DlrNavteq.h"
49 
50 
51 // ---------------------------------------------------------------------------
52 // static members
53 // ---------------------------------------------------------------------------
54 const std::string NIImporter_DlrNavteq::GEO_SCALE("1e-5");
55 const int NIImporter_DlrNavteq::EdgesHandler::MISSING_COLUMN = std::numeric_limits<int>::max();
56 const std::string NIImporter_DlrNavteq::UNDEFINED("-1");
57 
58 // ===========================================================================
59 // method definitions
60 // ===========================================================================
61 // ---------------------------------------------------------------------------
62 // static methods
63 // ---------------------------------------------------------------------------
64 void
66  // check whether the option is set (properly)
67  if (!oc.isSet("dlr-navteq-prefix")) {
68  return;
69  }
70  time_t csTime;
71  time(&csTime);
72  // parse file(s)
73  LineReader lr;
74  // load nodes
75  std::map<std::string, PositionVector> myGeoms;
76  PROGRESS_BEGIN_MESSAGE("Loading nodes");
77  std::string file = oc.getString("dlr-navteq-prefix") + "_nodes_unsplitted.txt";
78  NodesHandler handler1(nb.getNodeCont(), file, myGeoms);
79  if (!lr.setFile(file)) {
80  throw ProcessError("The file '" + file + "' could not be opened.");
81  }
82  lr.readAll(handler1);
84 
85  // load street names if given and wished
86  std::map<std::string, std::string> streetNames; // nameID : name
87  if (oc.getBool("output.street-names")) {
88  file = oc.getString("dlr-navteq-prefix") + "_names.txt";
89  if (lr.setFile(file)) {
90  PROGRESS_BEGIN_MESSAGE("Loading Street Names");
91  NamesHandler handler4(file, streetNames);
92  lr.readAll(handler4);
94  } else {
95  WRITE_WARNING("Output will not contain street names because the file '" + file + "' was not found");
96  }
97  }
98 
99  // load edges
100  PROGRESS_BEGIN_MESSAGE("Loading edges");
101  file = oc.getString("dlr-navteq-prefix") + "_links_unsplitted.txt";
102  // parse the file
103  EdgesHandler handler2(nb.getNodeCont(), nb.getEdgeCont(), nb.getTypeCont(), file, myGeoms, streetNames);
104  if (!lr.setFile(file)) {
105  throw ProcessError("The file '" + file + "' could not be opened.");
106  }
107  lr.readAll(handler2);
110 
111  // load traffic lights if given
112  file = oc.getString("dlr-navteq-prefix") + "_traffic_signals.txt";
113  if (lr.setFile(file)) {
114  PROGRESS_BEGIN_MESSAGE("Loading traffic lights");
115  TrafficlightsHandler handler3(nb.getNodeCont(), nb.getTLLogicCont(), nb.getEdgeCont(), file);
116  lr.readAll(handler3);
118  }
119 
120  // load prohibited manoeuvres if given
121  file = oc.getString("dlr-navteq-prefix") + "_prohibited_manoeuvres.txt";
122  if (lr.setFile(file)) {
123  PROGRESS_BEGIN_MESSAGE("Loading prohibited manoeuvres");
124  ProhibitionHandler handler6(nb.getEdgeCont(), file, csTime);
125  lr.readAll(handler6);
127  }
128 
129  // load connected lanes if given
130  file = oc.getString("dlr-navteq-prefix") + "_connected_lanes.txt";
131  if (lr.setFile(file)) {
132  PROGRESS_BEGIN_MESSAGE("Loading connected lanes");
133  ConnectedLanesHandler handler7(nb.getEdgeCont());
134  lr.readAll(handler7);
136  }
137 
138  // load time restrictions if given
139  file = oc.getString("dlr-navteq-prefix") + "_links_timerestrictions.txt";
140  if (lr.setFile(file)) {
141  PROGRESS_BEGIN_MESSAGE("Loading time restrictions");
142  if (!oc.isDefault("construction-date")) {
143  csTime = readDate(oc.getString("construction-date"));
144  }
145  TimeRestrictionsHandler handler5(nb.getEdgeCont(), nb.getDistrictCont(), csTime);
146  lr.readAll(handler5);
147  handler5.printSummary();
149  }
150 }
151 
152 double
153 NIImporter_DlrNavteq::readVersion(const std::string& line, const std::string& file) {
154  assert(line[0] == '#');
155  const std::string marker = "extraction version: v";
156  const std::string lowerCase = StringUtils::to_lower_case(line);
157  if (lowerCase.find(marker) == std::string::npos) {
158  return -1;
159  }
160  const int vStart = (int)(lowerCase.find(marker) + marker.size());
161  const int vEnd = (int)line.find(" ", vStart);
162  try {
163  const double version = StringUtils::toDouble(line.substr(vStart, vEnd - vStart));
164  if (version < 0) {
165  throw ProcessError("Invalid version number '" + toString(version) + "' in file '" + file + "'.");
166  }
167  return version;
168  } catch (NumberFormatException&) {
169  throw ProcessError("Non-numerical value '" + line.substr(vStart, vEnd - vStart) + "' for version string in file '" + file + "'.");
170  }
171 }
172 
173 
174 // ---------------------------------------------------------------------------
175 // definitions of NIImporter_DlrNavteq::NodesHandler-methods
176 // ---------------------------------------------------------------------------
178  const std::string& file,
179  std::map<std::string, PositionVector>& geoms)
180  : myNodeCont(nc), myGeoms(geoms) {
181  UNUSED_PARAMETER(file);
182 }
183 
184 
186 
187 
188 bool
189 NIImporter_DlrNavteq::NodesHandler::report(const std::string& result) {
190  if (result[0] == '#') {
191  return true;
192  }
193  std::string id;
194  double x, y;
195  int no_geoms, intermediate;
196  // parse
197  std::istringstream stream(result);
198  // id
199  stream >> id;
200  if (stream.fail()) {
201  throw ProcessError("Something is wrong with the following data line\n" + result);
202  }
203  // intermediate?
204  stream >> intermediate;
205  if (stream.fail()) {
206  if (myNodeCont.size() == 0) { // be generous with extra data at beginning of file
207  return true;
208  }
209  throw ProcessError("Non-numerical value for intermediate status in node " + id + ".");
210  }
211  // number of geometrical information
212  stream >> no_geoms;
213  if (stream.fail()) {
214  throw ProcessError("Non-numerical value for number of geometries in node " + id + ".");
215  }
216  // geometrical information
217  PositionVector geoms;
218  for (int i = 0; i < no_geoms; i++) {
219  stream >> x;
220  if (stream.fail()) {
221  throw ProcessError("Non-numerical value for x-position in node " + id + ".");
222  }
223  stream >> y;
224  if (stream.fail()) {
225  throw ProcessError("Non-numerical value for y-position in node " + id + ".");
226  }
227  Position pos(x, y);
228  if (!NBNetBuilder::transformCoordinate(pos, true)) {
229  throw ProcessError("Unable to project coordinates for node " + id + ".");
230  }
231  geoms.push_back(pos);
232  }
233 
234  if (intermediate == 0) {
235  NBNode* n = new NBNode(id, geoms[0]);
236  if (!myNodeCont.insert(n)) {
237  delete n;
238  throw ProcessError("Could not add node '" + id + "'.");
239  }
240  } else {
241  myGeoms[id] = geoms;
242  }
243  return true;
244 }
245 
246 
247 // ---------------------------------------------------------------------------
248 // definitions of NIImporter_DlrNavteq::EdgesHandler-methods
249 // ---------------------------------------------------------------------------
251  NBTypeCont& tc, const std::string& file,
252  std::map<std::string, PositionVector>& geoms,
253  std::map<std::string, std::string>& streetNames):
254  myNodeCont(nc),
255  myEdgeCont(ec),
256  myTypeCont(tc),
257  myGeoms(geoms),
258  myStreetNames(streetNames),
259  myVersion(0),
260  myFile(file) {
261 }
262 
263 
265 
266 
267 bool
268 NIImporter_DlrNavteq::EdgesHandler::report(const std::string& result) {
269  // parse version number from first comment line and initialize column definitions
270  if (result[0] == '#') {
271  if (!myColumns.empty()) {
272  return true;
273  }
274  const double version = readVersion(result, myFile);
275  if (version > 0) {
276  myVersion = version;
277  // init columns
278  const int NUM_COLUMNS = 25; // @note arrays must match this size!
279  const int MC = MISSING_COLUMN;
280  if (myVersion < 3) {
281  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};
282  myColumns = std::vector<int>(columns, columns + NUM_COLUMNS);
283  } else if (myVersion < 6) {
284  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};
285  myColumns = std::vector<int>(columns, columns + NUM_COLUMNS);
286  } else {
287  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};
288  myColumns = std::vector<int>(columns, columns + NUM_COLUMNS);
289  }
290  }
291  return true;
292  }
293  if (myColumns.empty()) {
294  throw ProcessError("Missing version string in file '" + myFile + "'.");
295  }
296  // interpret link attributes
298  const std::string id = getColumn(st, LINK_ID);
299  // form of way (for priority and permissions)
300  int form_of_way;
301  try {
302  form_of_way = StringUtils::toInt(getColumn(st, FORM_OF_WAY));
303  } catch (NumberFormatException&) {
304  throw ProcessError("Non-numerical value for form_of_way of link '" + id + "'.");
305  }
306  // brunnel type (bridge/tunnel/ferry (for permissions)
307  int brunnel_type;
308  try {
309  brunnel_type = StringUtils::toInt(getColumn(st, BRUNNEL_TYPE));
310  } catch (NumberFormatException&) {
311  throw ProcessError("Non-numerical value for brunnel_type of link '" + id + "'.");
312  }
313  // priority based on street_type / frc
314  int priority;
315  try {
317  // lower priority using form_of_way
318  if (form_of_way == 11) {
319  priority -= 1; // frontage road, very often with lowered curb
320  } else if (form_of_way > 11) {
321  priority -= 2; // parking/service access assume lowered curb
322  }
323  } catch (NumberFormatException&) {
324  throw ProcessError("Non-numerical value for street_type of link '" + id + "').");
325  }
326  // street name
327  std::string streetName = getStreetNameFromIDs(
330  // try to get the nodes
331  const std::string fromID = getColumn(st, NODE_ID_FROM);
332  const std::string toID = getColumn(st, NODE_ID_TO);
333  NBNode* from = myNodeCont.retrieve(fromID);
334  NBNode* to = myNodeCont.retrieve(toID);
335  if (from == nullptr) {
336  throw ProcessError("The from-node '" + fromID + "' of link '" + id + "' could not be found");
337  }
338  if (to == nullptr) {
339  throw ProcessError("The to-node '" + toID + "' of link '" + id + "' could not be found");
340  }
341  // speed
342  double speed;
343  try {
344  speed = StringUtils::toInt(getColumn(st, SPEED_RESTRICTION, "-1")) / 3.6;
345  } catch (NumberFormatException&) {
346  throw ProcessError("Non-numerical value for the SPEED_RESTRICTION of link '" + id + "'.");
347  }
348  if (speed < 0) {
349  // speed category as fallback
351  }
352  // number of lanes
353  int numLanes;
354  try {
355  // EXTENDED_NUMBER_OF_LANES is prefered but may not be defined
357  if (numLanes == -1) {
358  numLanes = NINavTeqHelper::getLaneNumber(id, getColumn(st, NUMBER_OF_LANES), speed);
359  }
360  } catch (NumberFormatException&) {
361  throw ProcessError("Non-numerical value for the number of lanes of link '" + id + "'.");
362  }
363 
364  const std::string navTeqTypeId = getColumn(st, VEHICLE_TYPE) + "_" + getColumn(st, FORM_OF_WAY);
365  // build the edge
366  NBEdge* e = nullptr;
367  const std::string interID = getColumn(st, BETWEEN_NODE_ID);
368  if (interID == "-1") {
369  e = new NBEdge(id, from, to, myTypeCont.knows(navTeqTypeId) ? navTeqTypeId : "", speed, numLanes, priority,
371  } else {
372  PositionVector geoms = myGeoms[interID];
373  if (getColumn(st, CONNECTION, "0") == "1") {
374  geoms = geoms.reverse();
375  }
376  geoms.insert(geoms.begin(), from->getPosition());
377  geoms.push_back(to->getPosition());
378  const std::string origID = OptionsCont::getOptions().getBool("output.original-names") ? id : "";
379  e = new NBEdge(id, from, to, myTypeCont.knows(navTeqTypeId) ? navTeqTypeId : "", speed, numLanes, priority,
381  }
382 
383  // NavTeq imports can be done with a typemap (if supplied), if not, the old defaults are used
384  if (myTypeCont.knows(navTeqTypeId)) {
385  e->setPermissions(myTypeCont.getPermissions(navTeqTypeId));
386  } else {
387  // add vehicle type information to the edge
388  if (myVersion < 6.0) {
390  } else {
392  }
393  if (e->getPermissions() == SVCAll) {
395  }
396  // permission modifications based on form_of_way
397  if (form_of_way == 14) { // pedestrian area (fussgaengerzone)
398  // unfortunately, the veh_type string is misleading in this case
400  }
401  // permission modifications based on brunnel_type
402  if (brunnel_type == 10) { // ferry
403  e->setPermissions(SVC_SHIP, -1);
404  }
405  }
406 
407  // insert the edge to the network
408  if (!myEdgeCont.insert(e)) {
409  delete e;
410  throw ProcessError("Could not add edge '" + id + "'.");
411  }
412  return true;
413 }
414 
415 
416 std::string
417 NIImporter_DlrNavteq::EdgesHandler::getColumn(const StringTokenizer& st, ColumnName name, const std::string fallback) {
418  assert(!myColumns.empty());
419  if (myColumns[name] == MISSING_COLUMN) {
420  if (fallback == "") {
421  throw ProcessError("Missing column " + toString(name) + ".");
422  } else {
423  return fallback;
424  }
425  } else if (myColumns[name] >= 0) {
426  return st.get((int)(myColumns[name]));
427  } else {
428  // negative column number implies an optional column
429  if ((int) st.size() <= -myColumns[name]) {
430  // the column is not present
431  if (fallback == "") {
432  throw ProcessError("Missing optional column " + toString(name) + " without default value.");
433  } else {
434  return fallback;
435  }
436  } else {
437  return st.get((int)(-myColumns[name]));
438  }
439  }
440 }
441 
442 
443 std::string
445  const std::string& regionalID, const std::string& localID) const {
446  std::string result = "";
447  bool hadRegional = false;
448  if (myStreetNames.count(regionalID) > 0) {
449  hadRegional = true;
450  result += myStreetNames[regionalID];
451  }
452  if (myStreetNames.count(localID) > 0) {
453  if (hadRegional) {
454  result += " / ";
455  }
456  result += myStreetNames[localID];
457  }
458  return result;
459 }
460 
461 // ---------------------------------------------------------------------------
462 // definitions of NIImporter_DlrNavteq::TrafficlightsHandler-methods
463 // ---------------------------------------------------------------------------
466  NBEdgeCont& ne,
467  const std::string& file) :
468  myNodeCont(nc),
469  myTLLogicCont(tlc),
470  myEdgeCont(ne) {
471  UNUSED_PARAMETER(file);
472 }
473 
474 
476 
477 
478 bool
480 // #ID POICOL-TYPE DESCRIPTION LONGITUDE LATITUDE NAVTEQ_LINK_ID NODEID
481 
482  if (result[0] == '#') {
483  return true;
484  }
486  const std::string edgeID = st.get(5);
487  NBEdge* edge = myEdgeCont.retrieve(edgeID);
488  if (edge == nullptr) {
489  WRITE_WARNING("The traffic light edge '" + edgeID + "' could not be found");
490  } else {
491  NBNode* node = edge->getToNode();
492  if (node->getType() != NODETYPE_TRAFFIC_LIGHT) {
493  node->reinit(node->getPosition(), NODETYPE_TRAFFIC_LIGHT);
494  // @note. There may be additional information somewhere in the GDF files about traffic light type ...
496  // @note actually we could use the navteq node ID here
497  NBTrafficLightDefinition* tlDef = new NBOwnTLDef(node->getID(), node, 0, type);
498  if (!myTLLogicCont.insert(tlDef)) {
499  // actually, nothing should fail here
500  delete tlDef;
501  throw ProcessError("Could not allocate tls for '" + node->getID() + "'.");
502  }
503  }
504  }
505  return true;
506 }
507 
508 
509 // ---------------------------------------------------------------------------
510 // definitions of NIImporter_DlrNavteq::NamesHandler-methods
511 // ---------------------------------------------------------------------------
513  const std::string& file, std::map<std::string, std::string>& streetNames) :
514  myStreetNames(streetNames) {
515  UNUSED_PARAMETER(file);
516 }
517 
518 
520 
521 
522 bool
523 NIImporter_DlrNavteq::NamesHandler::report(const std::string& result) {
524 // # NAME_ID Name
525  if (result[0] == '#') {
526  return true;
527  }
529  if (st.size() == 1) {
530  return true; // one line with the number of data containing lines in it (also starts with a comment # since ersion 6.5)
531  }
532  assert(st.size() >= 2);
533  const std::string id = st.next();
534  if (st.size() > 2) {
535  const std::string permanent_id_info = st.next();
536  }
537  myStreetNames[id] = st.next();
538  return true;
539 }
540 
541 
542 // ---------------------------------------------------------------------------
543 // definitions of NIImporter_DlrNavteq::TimeRestrictionsHandler-methods
544 // ---------------------------------------------------------------------------
546  myEdgeCont(ec),
547  myDistrictCont(dc),
548  myConstructionTime(constructionTime),
549  myCS_min(std::numeric_limits<time_t>::max()),
550  myCS_max(std::numeric_limits<time_t>::min()),
551  myConstructionEntries(0),
552  myNotStarted(0),
553  myUnderConstruction(0),
554  myFinished(0),
555  myRemovedEdges(0) {
556 }
557 
558 
560 
561 
562 bool
564 // # NAME_ID Name
565  if (result[0] == '#') {
566  return true;
567  }
569  const std::string id = st.next();
570  const std::string type = st.next();
571  const std::string directionOfFlow = st.next(); // can be ignored since unidirectional edge ids are referenced in the file
572  const std::string throughTraffic = st.next();
573  const std::string vehicleType = st.next();
574  const std::string validityPeriod = st.next();
575  const std::string warning = "Unrecognized TIME_REC '" + validityPeriod + "'";
576  if (type == "CS") {
578  if (validityPeriod.size() > 1024) {
579  WRITE_WARNING(warning);
580  }
581  // construction
582  char start[1024];
583  char duration[1024];
584 
585  int matched;
586 
587  matched = sscanf(validityPeriod.c_str(), "[(%[^)]){%[^}]}]", start, duration);
588  if (matched == 2) {
589  time_t tStart = readTimeRec(start, "");
590  time_t tEnd = readTimeRec(start, duration);
591  myCS_min = MIN2(myCS_min, tStart);
592  myCS_max = MAX2(myCS_max, tEnd);
593  //std::cout << " start=" << start << " tStart=" << tStart<< " translation=" << asctime(localtime(&tStart)) << "";
594  //std::cout << " duration=" << duration << " tEnd=" << tEnd << " translation=" << asctime(localtime(&tEnd)) << "\n";
595  if (myConstructionTime < tEnd) {
596  NBEdge* edge = myEdgeCont.retrieve(id);
597  if (edge != nullptr) {
598  myRemovedEdges++;
599  myEdgeCont.extract(myDistrictCont, edge, true);
600  }
601  if (myConstructionTime < tStart) {
602  myNotStarted++;
603  } else {
605  }
606  } else {
607  myFinished++;
608  }
609  } else {
610  WRITE_WARNING(warning);
611  };
612  }
613  return true;
614 }
615 
616 
617 void
619  if (myConstructionEntries > 0) {
620  char buff[1024];
621  std::ostringstream msg;
622  strftime(buff, 1024, "%Y-%m-%d", localtime(&myCS_min));
623  msg << "Parsed " << myConstructionEntries << " construction entries between " << buff;
624  strftime(buff, 1024, "%Y-%m-%d", localtime(&myCS_max));
625  msg << " and " << buff << ".\n";
626  strftime(buff, 1024, "%Y-%m-%d", localtime(&myConstructionTime));
627  msg << "Removed " << myRemovedEdges << " edges not yet constructed at " << buff << ".\n";
628  msg << " not yet started: " << myNotStarted << "\n";
629  msg << " under construction: " << myUnderConstruction << "\n";
630  msg << " finished: " << myFinished << "\n";
631  WRITE_MESSAGE(msg.str());
632  }
633 }
634 
635 
636 int
637 NIImporter_DlrNavteq::readPrefixedInt(const std::string& s, const std::string& prefix, int fallBack) {
638  int result = fallBack;
639  size_t pos = s.find(prefix);
640  if (pos != std::string::npos) {
641  sscanf(s.substr(pos).c_str(), (prefix + "%i").c_str(), &result);
642  }
643  return result;
644 }
645 
646 time_t
647 NIImporter_DlrNavteq::readTimeRec(const std::string& start, const std::string& duration) {
648  // http://www.cplusplus.com/reference/ctime/mktime/
649  struct tm timeinfo;
650  timeinfo.tm_hour = 0;
651  timeinfo.tm_min = 0;
652  timeinfo.tm_sec = 0;
653  timeinfo.tm_year = 0;
654  timeinfo.tm_mon = 0;
655  timeinfo.tm_mday = 1;
656  timeinfo.tm_wday = 0;
657  timeinfo.tm_yday = 0;
658  timeinfo.tm_isdst = 0;
659 
660  timeinfo.tm_year = readPrefixedInt(start, "y") + readPrefixedInt(duration, "y") - 1900;
661  timeinfo.tm_mon = readPrefixedInt(start, "M") + readPrefixedInt(duration, "M") - 1;
662  timeinfo.tm_mday = 7 * (readPrefixedInt(start, "w") + readPrefixedInt(duration, "w"));
663  timeinfo.tm_mday += readPrefixedInt(start, "d") + readPrefixedInt(duration, "d");
664 
665  time_t result = mktime(&timeinfo);
666  return result;
667 }
668 
669 
670 time_t
671 NIImporter_DlrNavteq::readDate(const std::string& yyyymmdd) {
672  struct tm timeinfo;
673  timeinfo.tm_hour = 0;
674  timeinfo.tm_min = 0;
675  timeinfo.tm_sec = 0;
676  timeinfo.tm_wday = 0;
677  timeinfo.tm_yday = 0;
678  timeinfo.tm_isdst = 0;
679 
680  if (yyyymmdd.size() == 10
681  && yyyymmdd[4] == '-'
682  && yyyymmdd[7] == '-') {
683  try {
684  timeinfo.tm_year = StringUtils::toInt(yyyymmdd.substr(0, 4)) - 1900;
685  timeinfo.tm_mon = StringUtils::toInt(yyyymmdd.substr(5, 2)) - 1;
686  timeinfo.tm_mday = StringUtils::toInt(yyyymmdd.substr(8, 2));
687  return mktime(&timeinfo);
688  } catch (...) {
689  }
690  }
691  WRITE_ERROR("Could not parse YYYY-MM-DD date '" + yyyymmdd + "'");
692  time_t now;
693  time(&now);
694  return now;
695 }
696 
697 // ---------------------------------------------------------------------------
698 // definitions of NIImporter_DlrNavteq::ProhibitionHandler-methods
699 // ---------------------------------------------------------------------------
701  NBEdgeCont& ec, const std::string& file, time_t constructionTime) :
702  myEdgeCont(ec),
703  myFile(file),
704  myVersion(0),
705  myConstructionTime(constructionTime) {
706 }
707 
708 
710 
711 
712 bool
714 // # NAME_ID Name
715  if (result[0] == '#') {
716  if (myVersion == 0) {
717  const double version = readVersion(result, myFile);
718  if (version > 0) {
719  myVersion = version;
720  }
721  }
722  return true;
723  }
725  if (st.size() == 1) {
726  return true; // one line with the number of data containing lines in it (also starts with a comment # since ersion 6.5)
727  }
728  if (myVersion >= 6) {
729  assert(st.size() >= 7);
730  const std::string id = st.next();
731  const std::string permanent = st.next();
732  const std::string validityPeriod = st.next();
733  const std::string throughTraffic = st.next();
734  const std::string vehicleType = st.next();
735  if (validityPeriod != UNDEFINED) {
736  WRITE_WARNING("Ignoring temporary prohibited manoeuvre (" + validityPeriod + ")");
737  return true;
738  }
739  }
740  const std::string startEdge = st.next();
741  const std::string endEdge = st.get(st.size() - 1);
742 
743  NBEdge* from = myEdgeCont.retrieve(startEdge);
744  if (from == nullptr) {
745  WRITE_WARNING("Ignoring prohibition from unknown start edge '" + startEdge + "'");
746  return true;
747  }
748  NBEdge* to = myEdgeCont.retrieve(endEdge);
749  if (to == nullptr) {
750  WRITE_WARNING("Ignoring prohibition from unknown end edge '" + endEdge + "'");
751  return true;
752  }
753  from->removeFromConnections(to, -1, -1, true);
754  return true;
755 }
756 
757 
758 // ---------------------------------------------------------------------------
759 // definitions of NIImporter_DlrNavteq::ConnectedLanesHandler-methods
760 // ---------------------------------------------------------------------------
762  NBEdgeCont& ec) :
763  myEdgeCont(ec) {
764 }
765 
766 
768 
769 
770 bool
772  if (result[0] == '#') {
773  return true;
774  }
776  if (st.size() == 1) {
777  return true; // one line with the number of data containing lines in it (also starts with a comment # since ersion 6.5)
778  }
779  assert(st.size() >= 7);
780  const std::string nodeID = st.next();
781  const std::string vehicleType = st.next();
782  const std::string fromLaneS = st.next();
783  const std::string toLaneS = st.next();
784  const std::string throughTraffic = st.next();
785  const std::string startEdge = st.next();
786  const std::string endEdge = st.get(st.size() - 1);
787 
788  NBEdge* from = myEdgeCont.retrieve(startEdge);
789  if (from == nullptr) {
790  WRITE_WARNING("Ignoring prohibition from unknown start edge '" + startEdge + "'");
791  return true;
792  }
793  NBEdge* to = myEdgeCont.retrieve(endEdge);
794  if (to == nullptr) {
795  WRITE_WARNING("Ignoring prohibition from unknown end edge '" + endEdge + "'");
796  return true;
797  }
798  int fromLane = StringUtils::toInt(fromLaneS) - 1; // one based
799  if (fromLane < 0 || fromLane >= from->getNumLanes()) {
800  WRITE_WARNING("Ignoring invalid lane index '" + fromLaneS + "' in connection from edge '" + startEdge + "' with " + toString(from->getNumLanes()) + " lanes");
801  return true;
802  }
803  int toLane = StringUtils::toInt(toLaneS) - 1; // one based
804  if (toLane < 0 || toLane >= to->getNumLanes()) {
805  WRITE_WARNING("Ignoring invalid lane index '" + toLaneS + "' in connection to edge '" + endEdge + "' with " + toString(to->getNumLanes()) + " lanes");
806  return true;
807  }
808  if (!from->addLane2LaneConnection(fromLane, to, toLane, NBEdge::L2L_USER, true)) {
809  if (OptionsCont::getOptions().getBool("show-errors.connections-first-try")) {
810  WRITE_WARNING("Could not set loaded connection from '" + from->getLaneID(fromLane) + "' to '" + to->getLaneID(toLane) + "'.");
811  }
812  // set as to be re-applied after network processing
813  // if this connection runs across a node cluster it may not be possible to set this
814  const bool warnOnly = st.size() > 7;
815  myEdgeCont.addPostProcessConnection(from->getID(), fromLane, to->getID(), toLane, false, true,
818  }
819  // ensure that connections for other lanes are guessed if not specified
821  from->getLaneStruct(fromLane).connectionsDone = true;
822  return true;
823 }
824 
825 /****************************************************************************/
bool report(const std::string &result)
Parsing method.
static const PositionVector EMPTY
empty Vector
NBEdgeCont & myEdgeCont
The edge container to store loaded edges into.
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:108
NBNodeCont & myNodeCont
The node container to get the referenced nodes from.
NBTypeCont & getTypeCont()
Returns a reference to the type container.
Definition: NBNetBuilder.h:160
bool report(const std::string &result)
Parsing method.
static bool transformCoordinate(Position &from, bool includeInBoundary=true, GeoConvHelper *from_srs=0)
transforms loaded coordinates handles projections, offsets (using GeoConvHelper) and import of height...
std::string next()
std::map< std::string, std::string > & myStreetNames
Previously read streat names (non-const because operate[] is more convenient)
static const double UNSPECIFIED_VISIBILITY_DISTANCE
unspecified foe visibility for connections
Definition: NBEdge.h:270
static double getSpeed(const std::string &id, const std::string &speedClassS)
Returns the speed evaluating the given Navteq-description.
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:51
void reinit(const Position &position, SumoXMLNodeType type, bool updateEdgeGeometries=false)
Resets initial values.
Definition: NBNode.cpp:286
bool report(const std::string &result)
Parsing method.
NodesHandler(NBNodeCont &nc, const std::string &file, std::map< std::string, PositionVector > &geoms)
Constructor.
The representation of a single edge during network building.
Definition: NBEdge.h:65
static const std::string UNDEFINED
magic value for undefined stuff
static void loadNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Loads content of the optionally given dlr-navteq (aka Elmar-fomat) folder.
A container for districts.
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 report(const std::string &result)
Parsing method.
std::string get(int pos) const
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:261
void removeFromConnections(NBEdge *toEdge, int fromLane=-1, int toLane=-1, bool tryLater=false, const bool adaptToLaneRemoval=false)
Removes the specified connection(s)
Definition: NBEdge.cpp:1281
T MAX2(T a, T b)
Definition: StdDefs.h:76
bool setFile(const std::string &file)
Reinitialises the reader for reading from the given file.
Definition: LineReader.cpp:178
bool report(const std::string &result)
Parsing method.
void setPermissions(SVCPermissions permissions, int lane=-1)
set allowed/disallowed classes for the given lane or for all lanes if -1 is given ...
Definition: NBEdge.cpp:3303
ProhibitionHandler(NBEdgeCont &ne, const std::string &file, time_t constructionTime)
Constructor.
NBEdgeCont & myEdgeCont
The edge container to store loaded edges into.
std::map< std::string, PositionVector > & myGeoms
Previously read edge geometries (manipulated during use)
PositionVector reverse() const
reverse position vector
Imports prohibitions regarding connectivity.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
bool connectionsDone
Whether connection information for this lane is already completed.
Definition: NBEdge.h:150
const std::string & getID() const
Returns the id.
Definition: Named.h:78
Importer of street names in DLRNavteq&#39;s (aka elmar) format.
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
const SVCPermissions SVCAll
all VClasses are allowed
NBTypeCont & myTypeCont
The type container to retrieve type info from.
Lane & getLaneStruct(int lane)
Definition: NBEdge.h:1206
Importer of traffic lights stored in DLRNavteq&#39;s (aka elmar) format.
bool report(const std::string &result)
Parsing method.
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:33
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:258
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:241
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
The edge has been loaded, nothing is computed yet.
Definition: NBEdge.h:86
static const double UNSPECIFIED_SPEED
unspecified lane speed
Definition: NBEdge.h:264
time_t myConstructionTime
The date for which to build the network (in case some edges are still under construction) ...
bool addLane2LaneConnection(int fromLane, NBEdge *dest, int toLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, bool keepClear=true, double contPos=UNSPECIFIED_CONTPOS, double visibility=UNSPECIFIED_VISIBILITY_DISTANCE, double speed=UNSPECIFIED_SPEED, const PositionVector &customShape=PositionVector::EMPTY, const bool uncontrolled=UNSPECIFIED_CONNECTION_UNCONTROLLED)
Adds a connection between the specified this edge&#39;s lane and an approached one.
Definition: NBEdge.cpp:998
Importer of edges stored in unsplit elmar format.
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
static double readVersion(const std::string &line, const std::string &file)
void readAll(LineHandler &lh)
Reads the whole file linewise, reporting every line to the given LineHandler.
Definition: LineReader.cpp:59
bool knows(const std::string &type) const
Returns whether the named type is in the container.
Definition: NBTypeCont.cpp:68
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
Definition: NBEdgeCont.cpp:152
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:49
NBEdgeCont & myEdgeCont
The edge container to store loaded edges into.
NamesHandler(const std::string &file, std::map< std::string, std::string > &streetNames)
Constructor.
int size() const
Returns the number of nodes stored in this container.
Definition: NBNodeCont.h:257
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter ...
std::string getLaneID(int lane) const
get Lane ID (Secure)
Definition: NBEdge.cpp:3022
void extract(NBDistrictCont &dc, NBEdge *edge, bool remember=false)
Removes the given edge from the container like erase but does not delete it.
Definition: NBEdgeCont.cpp:386
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:420
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
TimeRestrictionsHandler(NBEdgeCont &ec, NBDistrictCont &dc, time_t constructionTime)
Constructor.
NBEdgeCont & getEdgeCont()
Definition: NBNetBuilder.h:150
A list of positions.
static const double UNSPECIFIED_CONTPOS
unspecified internal junction position
Definition: NBEdge.h:267
T get(const std::string &str) const
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
static time_t readTimeRec(const std::string &start, const std::string &duration)
std::map< std::string, PositionVector > & myGeoms
A container for parsed geometries.
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:61
T MIN2(T a, T b)
Definition: StdDefs.h:70
const std::string myFile
the file being parsed
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:243
static int readPrefixedInt(const std::string &s, const std::string &prefix, int fallBack=0)
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter...
The connection was given by the user.
Definition: NBEdge.h:107
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition: NBEdge.cpp:3331
vehicle is a passenger car (a "normal" car)
static const int TAB
double myVersion
version number of current file
is an arbitrary ship
NBEdgeCont & myEdgeCont
The edge container to get the referenced edges from.
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:247
static void addVehicleClassesV6(NBEdge &e, const std::string &classS)
same as addVehicleClasses but for version 6+
static std::string to_lower_case(std::string str)
Transfers the content to lower case.
Definition: StringUtils.cpp:58
NBNodeCont & getNodeCont()
Returns a reference to the node container.
Definition: NBNetBuilder.h:155
Instance responsible for building networks.
Definition: NBNetBuilder.h:109
std::string getStreetNameFromIDs(const std::string &regionalID, const std::string &localID) const
build the street name for the given ids
void addPostProcessConnection(const std::string &from, int fromLane, const std::string &to, int toLane, bool mayDefinitelyPass, bool keepClear, double contPos, double visibility, double speed, const PositionVector &customShape, bool warnOnly=false)
Adds a connection which could not be set during loading.
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:245
A storage for options typed value containers)
Definition: OptionsCont.h:92
SumoXMLNodeType getType() const
Returns the type of this node.
Definition: NBNode.h:267
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
Definition: NBNodeCont.cpp:79
NBTrafficLightLogicCont & getTLLogicCont()
Returns a reference to the traffic light logics container.
Definition: NBNetBuilder.h:165
std::map< std::string, std::string > & myStreetNames
The container for storing read names.
NBTrafficLightLogicCont & myTLLogicCont
The traffic lights container to add built tls to.
EdgesHandler(NBNodeCont &nc, NBEdgeCont &ec, NBTypeCont &tc, const std::string &file, std::map< std::string, PositionVector > &geoms, std::map< std::string, std::string > &streetNames)
Constructor.
void declareConnectionsAsLoaded(EdgeBuildingStep step=LANES2LANES_USER)
declares connections as fully loaded. This is needed to avoid recomputing connections if an edge has ...
Definition: NBEdge.h:1220
const Position & getPosition() const
Definition: NBNode.h:242
Represents a single node (junction) during network building.
Definition: NBNode.h:68
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:991
static int getLaneNumber(const std::string &id, const std::string &laneNoS, double speed)
Returns the lane number evaluating the given Navteq-description.
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:60
TrafficlightsHandler(NBNodeCont &nc, NBTrafficLightLogicCont &tlc, NBEdgeCont &ne, const std::string &file)
Constructor.
#define PROGRESS_DONE_MESSAGE()
Definition: MsgHandler.h:244
A traffic light logics which must be computed (only nodes/edges are given)
Definition: NBOwnTLDef.h:47
static const std::string GEO_SCALE
scaling factor for geo coordinates (DLRNavteq format uses this to increase floating point precisions)...
static time_t readDate(const std::string &yyyymmdd)
Imports prohibitions regarding connectivity.
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:242
NBDistrictCont & getDistrictCont()
Returns a reference the districts container.
Definition: NBNetBuilder.h:170
std::vector< int > myColumns
the version number of the edge file being parsed
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:441
void disallowVehicleClass(int lane, SUMOVehicleClass vclass)
set disallowed class for the given lane or for all lanes if -1 is given
Definition: NBEdge.cpp:3148
TrafficLightType
SVCPermissions getPermissions(const std::string &type) const
Returns allowed vehicle classes for the given type.
Definition: NBTypeCont.cpp:204
A storage for available types of edges.
Definition: NBTypeCont.h:55
std::string getColumn(const StringTokenizer &st, ColumnName name, const std::string fallback="")
bool report(const std::string &result)
Parsing method.