SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NLHandler.cpp
Go to the documentation of this file.
1 /****************************************************************************/
12 // The XML-Handler for network loading
13 /****************************************************************************/
14 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
15 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
16 /****************************************************************************/
17 //
18 // This file is part of SUMO.
19 // SUMO is free software: you can redistribute it and/or modify
20 // it under the terms of the GNU General Public License as published by
21 // the Free Software Foundation, either version 3 of the License, or
22 // (at your option) any later version.
23 //
24 /****************************************************************************/
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #include <string>
35 #include "NLHandler.h"
36 #include "NLEdgeControlBuilder.h"
38 #include "NLDetectorBuilder.h"
39 #include "NLTriggerBuilder.h"
43 #include <utils/common/SUMOTime.h>
47 #include <utils/common/RGBColor.h>
49 #include <microsim/MSGlobals.h>
50 #include <microsim/MSLane.h>
52 #include <microsim/MSBitSetLogic.h>
61 
62 #ifdef CHECK_MEMORY_LEAKS
63 #include <foreign/nvwa/debug_new.h>
64 #endif // CHECK_MEMORY_LEAKS
65 
66 
67 // ===========================================================================
68 // method definitions
69 // ===========================================================================
70 NLHandler::NLHandler(const std::string& file, MSNet& net,
71  NLDetectorBuilder& detBuilder,
72  NLTriggerBuilder& triggerBuilder,
73  NLEdgeControlBuilder& edgeBuilder,
74  NLJunctionControlBuilder& junctionBuilder)
75  : MSRouteHandler(file, true),
76  myNet(net), myActionBuilder(net),
77  myCurrentIsInternalToSkip(false),
78  myDetectorBuilder(detBuilder), myTriggerBuilder(triggerBuilder),
79  myEdgeControlBuilder(edgeBuilder), myJunctionControlBuilder(junctionBuilder),
80  mySucceedingLaneBuilder(junctionBuilder),
81  myAmInTLLogicMode(false), myCurrentIsBroken(false),
82  myHaveWarnedAboutDeprecatedE1(false),
83  myHaveWarnedAboutDeprecatedE2(false),
84  myHaveWarnedAboutDeprecatedE3(false),
85  myHaveWarnedAboutDeprecatedDetEntry(false),
86  myHaveWarnedAboutDeprecatedDetExit(false),
87  myHaveWarnedAboutDeprecatedRowLogic(false),
88  myHaveWarnedAboutDeprecatedTLLogic(false),
89  myHaveWarnedAboutDeprecatedTimedEvent(false),
90  myHaveWarnedAboutDeprecatedTLSTiming(false),
91  myHaveWarnedAboutDeprecatedTimeThreshold(false),
92  myHaveWarnedAboutDeprecatedSpeedThreshold(false),
93  myHaveWarnedAboutDeprecatedJamDistThreshold(false),
94  myHaveWarnedAboutDeprecatedVTypeProbe(false),
95  myHaveWarnedAboutDeprecatedRouteProbe(false),
96  myHaveWarnedAboutDeprecatedEdgeMean(false),
97  myHaveWarnedAboutDeprecatedLaneMean(false),
98  myHaveWarnedAboutDeprecatedVTypes(false),
99  myHaveWarnedAboutDeprecatedLanes(false),
100  myHaveWarnedAboutDeprecatedDistrict(false), myHaveWarnedAboutDeprecatedDSource(false), myHaveWarnedAboutDeprecatedDSink(false) {}
101 
102 
104 
105 
106 void
108  const SUMOSAXAttributes& attrs) {
109  try {
110  switch (element) {
111  case SUMO_TAG_EDGE:
112  beginEdgeParsing(attrs);
113  break;
114  case SUMO_TAG_LANE:
115  addLane(attrs);
116  break;
117  case SUMO_TAG_POLY:
118  addPoly(attrs);
119  break;
120  case SUMO_TAG_POI:
121  addPOI(attrs);
122  break;
123  case SUMO_TAG_JUNCTION:
124  openJunction(attrs);
125  initJunctionLogic(attrs);
126  break;
127  case SUMO_TAG_PHASE:
128  addPhase(attrs);
129  break;
130  case SUMO_TAG_SUCC:
131  openSucc(attrs);
132  break;
133  case SUMO_TAG_SUCCLANE:
134  addSuccLane(attrs);
135  break;
136  case SUMO_TAG_CONNECTION:
137  addConnection(attrs);
138  break;
142  WRITE_WARNING("Your network uses deprecated tags; please rebuild.");
143  }
144  initJunctionLogic(attrs);
145  break;
149  WRITE_WARNING("Deprecated tl-logic name; please rebuild.");
150  }
151  case SUMO_TAG_TLLOGIC:
152  initTrafficLightLogic(attrs);
153  break;
154  case SUMO_TAG_LOGICITEM: // deprecated
155  addLogicItem(attrs);
156  break;
157  case SUMO_TAG_REQUEST:
158  addRequest(attrs);
159  break;
160  case SUMO_TAG_WAUT:
161  openWAUT(attrs);
162  break;
164  addWAUTSwitch(attrs);
165  break;
167  addWAUTJunction(attrs);
168  break;
169 #ifdef _MESSAGES
170  case SUMO_TAG_MSG_EMITTER:
171  addMsgEmitter(attrs);
172  break;
173 #endif
177  WRITE_WARNING("'" + toString(SUMO_TAG_E1DETECTOR__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_E1DETECTOR) + "'.");
178  }
179  case SUMO_TAG_E1DETECTOR:
181  addE1Detector(attrs);
182  break;
186  WRITE_WARNING("'" + toString(SUMO_TAG_E2DETECTOR__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_E2DETECTOR) + "'.");
187  }
188  case SUMO_TAG_E2DETECTOR:
190  addE2Detector(attrs);
191  break;
195  WRITE_WARNING("'" + toString(SUMO_TAG_E3DETECTOR__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_E3DETECTOR) + "'.");
196  }
197  case SUMO_TAG_E3DETECTOR:
199  beginE3Detector(attrs);
200  break;
204  WRITE_WARNING("'" + toString(SUMO_TAG_DET_ENTRY__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_DET_ENTRY) + "'.");
205  }
206  case SUMO_TAG_DET_ENTRY:
207  addE3Entry(attrs);
208  break;
212  WRITE_WARNING("'" + toString(SUMO_TAG_DET_EXIT__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_DET_EXIT) + "'.");
213  }
214  case SUMO_TAG_DET_EXIT:
215  addE3Exit(attrs);
216  break;
218  addInstantE1Detector(attrs);
219  break;
220  case SUMO_TAG_VSS:
222  break;
223 #ifdef HAVE_MESOSIM
224  case SUMO_TAG_CALIBRATOR:
225  myTriggerBuilder.parseAndBuildCalibrator(myNet, attrs, getFileName());
226  break;
227 #endif
228  case SUMO_TAG_REROUTER:
230  break;
231  case SUMO_TAG_BUS_STOP:
233  break;
237  WRITE_WARNING("'" + toString(SUMO_TAG_VTYPEPROBE__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_VTYPEPROBE) + "'.");
238  }
239  case SUMO_TAG_VTYPEPROBE:
240  addVTypeProbeDetector(attrs);
241  break;
245  WRITE_WARNING("'" + toString(SUMO_TAG_ROUTEPROBE__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_ROUTEPROBE) + "'.");
246  }
247  case SUMO_TAG_ROUTEPROBE:
248  addRouteProbeDetector(attrs);
249  break;
253  WRITE_WARNING("'" + toString(SUMO_TAG_MEANDATA_EDGE__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_MEANDATA_EDGE) + "'.");
254  }
257  break;
261  WRITE_WARNING("'" + toString(SUMO_TAG_MEANDATA_LANE__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_MEANDATA_LANE) + "'.");
262  }
265  break;
269  WRITE_WARNING("'" + toString(SUMO_TAG_TIMEDEVENT__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_TIMEDEVENT) + "'.");
270  }
271  case SUMO_TAG_TIMEDEVENT:
273  break;
274  case SUMO_TAG_VAPORIZER:
276  break;
277  case SUMO_TAG_LOCATION:
278  setLocation(attrs);
279  break;
283  WRITE_WARNING("'" + toString(SUMO_TAG_DISTRICT__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_TAG_TAZ) + "'.");
284  }
285  case SUMO_TAG_TAZ:
286  addDistrict(attrs);
287  break;
291  WRITE_WARNING("'" + toString(SUMO_TAG_DSOURCE__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_TAG_TAZSOURCE) + "'.");
292  }
293  case SUMO_TAG_TAZSOURCE:
294  addDistrictEdge(attrs, true);
295  break;
299  WRITE_WARNING("'" + toString(SUMO_TAG_DSINK__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_TAG_TAZSINK) + "'.");
300  }
301  case SUMO_TAG_TAZSINK:
302  addDistrictEdge(attrs, false);
303  break;
304  default:
305  break;
306  }
307  } catch (InvalidArgument& e) {
308  WRITE_ERROR(e.what());
309  }
310  MSRouteHandler::myStartElement(element, attrs);
311  if (element == SUMO_TAG_PARAM) {
312  addParam(attrs);
313  }
314 }
315 
316 
317 void
319  switch (element) {
320  case SUMO_TAG_EDGE:
321  closeEdge();
322  break;
323  case SUMO_TAG_JUNCTION:
324  if (!myCurrentIsBroken) {
325  try {
328  } catch (InvalidArgument& e) {
329  WRITE_ERROR(e.what());
330  }
331  }
332  break;
333  case SUMO_TAG_SUCC:
334  closeSuccLane();
335  break;
337  try {
339  } catch (InvalidArgument& e) {
340  WRITE_ERROR(e.what());
341  }
342  break;
344  case SUMO_TAG_TLLOGIC:
345  try {
347  } catch (InvalidArgument& e) {
348  WRITE_ERROR(e.what());
349  }
350  myAmInTLLogicMode = false;
351  break;
352  case SUMO_TAG_WAUT:
353  closeWAUT();
354  break;
356  case SUMO_TAG_E3DETECTOR:
358  endE3Detector();
359  break;
360  default:
361  break;
362  }
364 }
365 
366 
367 
368 // ---- the root/edge - element
369 void
371  bool ok = true;
372  myCurrentIsBroken = false;
373  // get the id, report an error if not given or empty...
374  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
375  if (!ok) {
376  myCurrentIsBroken = true;
377  return;
378  }
379  // omit internal edges if not wished
380  if (!MSGlobals::gUsingInternalLanes && id[0] == ':') {
382  return;
383  }
385  // parse the function
387  std::string funcString = attrs.getOptStringReporting(SUMO_ATTR_FUNCTION, id.c_str(), ok, toString(func));
388  if (!ok) {
389  myCurrentIsBroken = true;
390  return;
391  }
392  if (SUMOXMLDefinitions::EdgeFunctions.hasString(funcString)) {
393  func = SUMOXMLDefinitions::EdgeFunctions.get(funcString);
394  } else {
395  WRITE_ERROR("Edge '" + id + "' has an invalid type ('" + funcString + "').");
396  myCurrentIsBroken = true;
397  return;
398  }
399  // interpret the function
401  switch (func) {
402  case EDGEFUNC_NORMAL:
403  funcEnum = MSEdge::EDGEFUNCTION_NORMAL;
404  break;
405  case EDGEFUNC_CONNECTOR:
406  case EDGEFUNC_SINK:
407  case EDGEFUNC_SOURCE:
409  break;
410  case EDGEFUNC_INTERNAL:
412  break;
413  }
414  // get the street name
415  std::string streetName = attrs.getOptStringReporting(SUMO_ATTR_NAME, id.c_str(), ok, "");
416  if (!ok) {
417  myCurrentIsBroken = true;
418  return;
419  }
420  //
421  try {
422  myEdgeControlBuilder.beginEdgeParsing(id, funcEnum, streetName);
423  } catch (InvalidArgument& e) {
424  WRITE_ERROR(e.what());
425  myCurrentIsBroken = true;
426  }
427 }
428 
429 
430 void
432  // omit internal edges if not wished and broken edges
434  return;
435  }
436  try {
438  MSEdge::dictionary(e->getID(), e);
439  } catch (InvalidArgument& e) {
440  WRITE_ERROR(e.what());
441  }
442 }
443 
444 
445 // ---- the root/edge/lanes/lane - element
446 void
448  // omit internal edges if not wished and broken edges
450  return;
451  }
452  bool ok = true;
453  // get the id, report an error if not given or empty...
454  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
455  if (!ok) {
456  myCurrentIsBroken = true;
457  return;
458  }
459  SUMOReal maxSpeed = attrs.hasAttribute(SUMO_ATTR_SPEED)
460  ? attrs.getSUMORealReporting(SUMO_ATTR_SPEED, id.c_str(), ok)
461  : attrs.getSUMORealReporting(SUMO_ATTR_MAXSPEED__DEPRECATED, id.c_str(), ok);
462  SUMOReal length = attrs.getSUMORealReporting(SUMO_ATTR_LENGTH, id.c_str(), ok);
463  std::string allow = attrs.getOptStringReporting(SUMO_ATTR_ALLOW, id.c_str(), ok, "");
464  std::string disallow = attrs.getOptStringReporting(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
466  int index = attrs.getOptIntReporting(SUMO_ATTR_INDEX, id.c_str(), ok, -1);
467  PositionVector shape = GeomConvHelper::parseShapeReporting(attrs.getStringReporting(SUMO_ATTR_SHAPE, id.c_str(), ok), "lane", id.c_str(), ok, false);
468  if (shape.size() < 2) {
469  WRITE_ERROR("Shape of lane '" + id + "' is broken.\n Can not build according edge.");
470  myCurrentIsBroken = true;
471  return;
472  }
473  SVCPermissions permissions = parseVehicleClasses(allow, disallow);
474  myCurrentIsBroken |= !ok;
475  if (!myCurrentIsBroken) {
476  try {
477  MSLane* lane = myEdgeControlBuilder.addLane(id, maxSpeed, length, shape, width, permissions);
478  // insert the lane into the lane-dictionary, checking
479  if (!MSLane::dictionary(id, lane)) {
480  delete lane;
481  WRITE_ERROR("Another lane with the id '" + id + "' exists.");
482  myCurrentIsBroken = true;
483  }
484  } catch (InvalidArgument& e) {
485  WRITE_ERROR(e.what());
486  }
487  }
488 }
489 
490 
491 // ---- the root/junction - element
492 void
494  myCurrentIsBroken = false;
495  bool ok = true;
496  // get the id, report an error if not given or empty...
497  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
498  if (!ok) {
499  myCurrentIsBroken = true;
500  return;
501  }
502  PositionVector shape;
503  if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
504  // inner junctions have no shape
505  shape = GeomConvHelper::parseShapeReporting(attrs.getStringSecure(SUMO_ATTR_SHAPE, ""), attrs.getObjectType(), id.c_str(), ok, true);
506  }
507  SUMOReal x = attrs.getSUMORealReporting(SUMO_ATTR_X, id.c_str(), ok);
508  SUMOReal y = attrs.getSUMORealReporting(SUMO_ATTR_Y, id.c_str(), ok);
509  std::string type = attrs.getStringReporting(SUMO_ATTR_TYPE, id.c_str(), ok);
510  std::string key = attrs.getOptStringReporting(SUMO_ATTR_KEY, id.c_str(), ok, "");
511  // incoming lanes
512  std::vector<MSLane*> incomingLanes;
513  parseLanes(id, attrs.getStringSecure(SUMO_ATTR_INCLANES, ""), incomingLanes, ok);
514  // internal lanes
515  std::vector<MSLane*> internalLanes;
516 #ifdef HAVE_INTERNAL_LANES
518  parseLanes(id, attrs.getStringSecure(SUMO_ATTR_INTLANES, ""), internalLanes, ok);
519  }
520 #endif
521  if (!ok) {
522  myCurrentIsBroken = true;
523  } else {
524  try {
525  myJunctionControlBuilder.openJunction(id, key, type, x, y, shape, incomingLanes, internalLanes);
526  } catch (InvalidArgument& e) {
527  WRITE_ERROR(e.what() + std::string("\n Can not build according junction."));
528  myCurrentIsBroken = true;
529  }
530  }
531 }
532 
533 
534 void
535 NLHandler::parseLanes(const std::string& junctionID,
536  const std::string& def, std::vector<MSLane*> &into, bool& ok) {
537  StringTokenizer st(def);
538  while (ok && st.hasNext()) {
539  std::string laneID = st.next();
540  MSLane* lane = MSLane::dictionary(laneID);
541  if (!MSGlobals::gUsingInternalLanes && laneID[0] == ':') {
542  continue;
543  }
544  if (lane == 0) {
545  WRITE_ERROR("An unknown lane ('" + laneID + "') was tried to be set as incoming to junction '" + junctionID + "'.");
546  ok = false;
547  continue;
548  }
549  into.push_back(lane);
550  }
551 }
552 // ----
553 
554 void
556  bool ok = true;
557  std::string key = attrs.getStringReporting(SUMO_ATTR_KEY, 0, ok);
558  std::string val = attrs.getStringReporting(SUMO_ATTR_VALUE, 0, ok);
559  // set
560  if (ok && myAmInTLLogicMode) {
561  assert(key != "");
562  assert(val != "");
564  }
565 }
566 
567 
568 void
570  myCurrentIsBroken = false;
571  bool ok = true;
572  // get the id, report an error if not given or empty...
573  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
574  if (!ok) {
575  myCurrentIsBroken = true;
576  return;
577  }
578  SUMOTime t = attrs.getOptSUMOTimeReporting(SUMO_ATTR_REF_TIME, id.c_str(), ok, 0);
579  std::string pro = attrs.getStringReporting(SUMO_ATTR_START_PROG, id.c_str(), ok);
580  if (!ok) {
581  myCurrentIsBroken = true;
582  }
583  if (!myCurrentIsBroken) {
584  myCurrentWAUTID = id;
585  try {
587  } catch (InvalidArgument& e) {
588  WRITE_ERROR(e.what());
589  myCurrentIsBroken = true;
590  }
591  }
592 }
593 
594 
595 void
597  bool ok = true;
599  std::string to = attrs.getStringReporting(SUMO_ATTR_TO, myCurrentWAUTID.c_str(), ok);
600  if (!ok) {
601  myCurrentIsBroken = true;
602  }
603  if (!myCurrentIsBroken) {
604  try {
606  } catch (InvalidArgument& e) {
607  WRITE_ERROR(e.what());
608  myCurrentIsBroken = true;
609  }
610  }
611 }
612 
613 
614 void
616  bool ok = true;
617  std::string wautID = attrs.getStringReporting(SUMO_ATTR_WAUT_ID, 0, ok);
618  std::string junctionID = attrs.getStringReporting(SUMO_ATTR_JUNCTION_ID, 0, ok);
619  std::string procedure = attrs.getOptStringReporting(SUMO_ATTR_PROCEDURE, 0, ok, "");
620  bool synchron = attrs.getOptBoolReporting(SUMO_ATTR_SYNCHRON, 0, ok, false);
621  if (!ok) {
622  myCurrentIsBroken = true;
623  }
624  try {
625  if (!myCurrentIsBroken) {
626  myJunctionControlBuilder.getTLLogicControlToUse().addWAUTJunction(wautID, junctionID, procedure, synchron);
627  }
628  } catch (InvalidArgument& e) {
629  WRITE_ERROR(e.what());
630  myCurrentIsBroken = true;
631  }
632 }
633 
634 
635 
636 
637 
638 
639 
640 void
642  bool ok = true;
643  const SUMOReal INVALID_POSITION(-1000000);
644  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
645  SUMOReal x = attrs.getOptSUMORealReporting(SUMO_ATTR_X, id.c_str(), ok, INVALID_POSITION);
646  SUMOReal y = attrs.getOptSUMORealReporting(SUMO_ATTR_Y, id.c_str(), ok, INVALID_POSITION);
647  SUMOReal lanePos = attrs.getOptSUMORealReporting(SUMO_ATTR_POSITION, id.c_str(), ok, INVALID_POSITION);
648  int layer = attrs.getOptIntReporting(SUMO_ATTR_LAYER, id.c_str(), ok, GLO_SHAPE);
649  std::string type = attrs.getOptStringReporting(SUMO_ATTR_TYPE, id.c_str(), ok, "");
650  std::string laneID = attrs.getOptStringReporting(SUMO_ATTR_LANE, id.c_str(), ok, "");
651  std::string colorStr = attrs.getOptStringReporting(SUMO_ATTR_COLOR, id.c_str(), ok, "1,0,0");
652  RGBColor color = RGBColor::parseColorReporting(colorStr, attrs.getObjectType(), id.c_str(), true, ok);
653  if (!ok) {
654  return;
655  }
656  Position pos(x, y);
657  if (x == INVALID_POSITION || y == INVALID_POSITION) {
658  MSLane* lane = MSLane::dictionary(laneID);
659  if (lane == 0) {
660  WRITE_ERROR("Lane '" + laneID + "' to place a poi '" + id + "'on is not known.");
661  return;
662  }
663  if (lanePos < 0) {
664  lanePos = lane->getLength() + lanePos;
665  }
666  pos = lane->getShape().positionAtLengthPosition(lanePos);
667  }
668  if (!myNet.getShapeContainer().addPoI(id, layer, type, color, pos)) {
669  WRITE_ERROR("PoI '" + id + "' already exists.");
670  }
671 }
672 
673 
674 void
676  bool ok = true;
677  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
678  // get the id, report an error if not given or empty...
679  if (!ok) {
680  return;
681  }
682  int layer = attrs.getOptIntReporting(SUMO_ATTR_LAYER, id.c_str(), ok, GLO_SHAPE);
683  bool fill = attrs.getOptBoolReporting(SUMO_ATTR_FILL, id.c_str(), ok, false);
684  std::string type = attrs.getOptStringReporting(SUMO_ATTR_TYPE, id.c_str(), ok, "");
685  std::string colorStr = attrs.getStringReporting(SUMO_ATTR_COLOR, id.c_str(), ok);
686  RGBColor color = RGBColor::parseColorReporting(colorStr, attrs.getObjectType(), id.c_str(), true, ok);
687  PositionVector shape = GeomConvHelper::parseShapeReporting(attrs.getStringReporting(SUMO_ATTR_SHAPE, id.c_str(), ok), attrs.getObjectType(), id.c_str(), ok, false);
688  if (shape.size() != 0) {
689  if (!myNet.getShapeContainer().addPolygon(id, layer, type, color, fill, shape)) {
690  WRITE_ERROR("Polygon '" + id + "' already exists.");
691  }
692  }
693 }
694 
695 
696 void
698  bool ok = true;
699  int request = attrs.getIntReporting(SUMO_ATTR_REQUEST, 0, ok);
700  bool cont = false;
701 #ifdef HAVE_INTERNAL_LANES
702  cont = attrs.getOptBoolReporting(SUMO_ATTR_CONT, 0, ok, false);
703 #endif
704  std::string response = attrs.getStringReporting(SUMO_ATTR_RESPONSE, 0, ok);
705  std::string foes = attrs.getStringReporting(SUMO_ATTR_FOES, 0, ok);
706  if (!ok) {
707  return;
708  }
709  // store received information
710  if (request >= 0 && response.length() > 0) {
711  try {
712  myJunctionControlBuilder.addLogicItem(request, response, foes, cont);
713  } catch (InvalidArgument& e) {
714  WRITE_ERROR(e.what());
715  }
716  }
717 }
718 
719 
720 void
722  if (myCurrentIsBroken) {
723  return;
724  }
725  bool ok = true;
726  int request = attrs.getIntReporting(SUMO_ATTR_INDEX, 0, ok);
727  bool cont = false;
728 #ifdef HAVE_INTERNAL_LANES
729  cont = attrs.getOptBoolReporting(SUMO_ATTR_CONT, 0, ok, false);
730 #endif
731  std::string response = attrs.getStringReporting(SUMO_ATTR_RESPONSE, 0, ok);
732  std::string foes = attrs.getStringReporting(SUMO_ATTR_FOES, 0, ok);
733  if (!ok) {
734  return;
735  }
736  // store received information
737  if (request >= 0 && response.length() > 0) {
738  try {
739  myJunctionControlBuilder.addLogicItem(request, response, foes, cont);
740  } catch (InvalidArgument& e) {
741  WRITE_ERROR(e.what());
742  }
743  }
744 }
745 
746 
747 void
749  if (myCurrentIsBroken) {
750  return;
751  }
752  bool ok = true;
753  // we either a have a junction or a legacy network with ROWLogic
754  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
755  if (ok) {
757  }
758 }
759 
760 
761 void
763  myAmInTLLogicMode = true;
764  bool ok = true;
765  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
766  TrafficLightType type;
767  std::string typeS = attrs.getStringReporting(SUMO_ATTR_TYPE, 0, ok);
768  if (SUMOXMLDefinitions::TrafficLightTypes.hasString(typeS)) {
770  } else {
771  WRITE_ERROR("Traffic light '" + id + "' has unknown type '" + typeS + "'");
772  return;
773  }
774  //
775  SUMOTime offset = attrs.getOptSUMOTimeReporting(SUMO_ATTR_OFFSET, id.c_str(), ok, 0);
776  if (!ok) {
777  return;
778  }
779  std::string programID = attrs.getOptStringReporting(SUMO_ATTR_PROGRAMID, id.c_str(), ok, "<unknown>");
780  myJunctionControlBuilder.initTrafficLightLogic(id, programID, type, offset);
781 }
782 
783 
784 void
786  // try to get the phase definition
787  bool ok = true;
788  std::string state = attrs.getStringReporting(SUMO_ATTR_STATE, 0, ok);
789  if (!ok) {
790  return;
791  }
792  // try to get the phase duration
794  if (duration == 0) {
795  WRITE_ERROR("Duration of tls-logic '" + myJunctionControlBuilder.getActiveKey() + "/" + myJunctionControlBuilder.getActiveSubKey() + "' is zero.");
796  return;
797  }
798  // if the traffic light is an actuated traffic light, try to get
799  // the minimum and maximum durations
800  SUMOTime minDuration = -1;
805  WRITE_WARNING("Your tls definition contains deprecated minimum/maximum duration attribute; use minDur and maxDur instead.");
806  }
807  } else {
809  }
810  SUMOTime maxDuration = -1;
815  WRITE_WARNING("Your tls definition contains deprecated minimum/maximum duration attribute; use minDur and maxDur instead.");
816  }
817  } else {
819  }
820  myJunctionControlBuilder.addPhase(duration, state, minDuration, maxDuration);
821 }
822 
823 
824 #ifdef _MESSAGES
825 void
826 NLHandler::addMsgEmitter(const SUMOSAXAttributes& attrs) {
827  bool ok = true;
828  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
829  std::string file = attrs.getOptStringReporting(SUMO_ATTR_FILE, 0, ok, "");
830  // if no file given, use stdout
831  if (file == "") {
832  file = "-";
833  }
834  SUMOTime step = attrs.getOptSUMOTimeReporting(SUMO_ATTR_STEP, id.c_str(), ok, 1);
835  bool reverse = attrs.getOptBoolReporting(SUMO_ATTR_REVERSE, 0, ok, false);
836  bool table = attrs.getOptBoolReporting(SUMO_ATTR_TABLE, 0, ok, false);
837  bool xycoord = attrs.getOptBoolReporting(SUMO_ATTR_XY, 0, ok, false);
838  std::string whatemit = attrs.getStringReporting(SUMO_ATTR_EVENTS, 0, ok);
839  if (!ok) {
840  return;
841  }
842  myNet.createMsgEmitter(id, file, getFileName(), whatemit, reverse, table, xycoord, step);
843 }
844 #endif
845 
846 
847 void
849  bool ok = true;
850  // get the id, report an error if not given or empty...
851  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
852  if (!ok) {
853  return;
854  }
855  // inform the user about deprecated values
856  const SUMOTime frequency = attrs.getSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok);
857  const SUMOReal position = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, id.c_str(), ok);
858  const bool friendlyPos = attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
859  const bool splitByType = attrs.getOptBoolReporting(SUMO_ATTR_SPLIT_VTYPE, id.c_str(), ok, false);
860  const std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, id.c_str(), ok);
861  const std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, id.c_str(), ok);
862  if (!ok) {
863  return;
864  }
865  try {
866  myDetectorBuilder.buildInductLoop(id, lane, position, frequency,
868  friendlyPos, splitByType);
869  } catch (InvalidArgument& e) {
870  WRITE_ERROR(e.what());
871  } catch (IOError& e) {
872  WRITE_ERROR(e.what());
873  }
874 }
875 
876 
877 void
879  bool ok = true;
880  // get the id, report an error if not given or empty...
881  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
882  if (!ok) {
883  return;
884  }
885  // inform the user about deprecated values
886  const SUMOReal position = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, id.c_str(), ok);
887  const bool friendlyPos = attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
888  const std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, id.c_str(), ok);
889  const std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, id.c_str(), ok);
890  if (!ok) {
891  return;
892  }
893  try {
894  myDetectorBuilder.buildInstantInductLoop(id, lane, position, OutputDevice::getDevice(file, getFileName()), friendlyPos);
895  } catch (InvalidArgument& e) {
896  WRITE_ERROR(e.what());
897  } catch (IOError& e) {
898  WRITE_ERROR(e.what());
899  }
900 }
901 
902 
903 void
905  bool ok = true;
906  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
907  SUMOTime frequency = attrs.getSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok);
908  std::string type = attrs.getStringSecure(SUMO_ATTR_TYPE, "");
909  std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, id.c_str(), ok);
910  if (!ok) {
911  return;
912  }
913  try {
915  } catch (InvalidArgument& e) {
916  WRITE_ERROR(e.what());
917  } catch (IOError& e) {
918  WRITE_ERROR(e.what());
919  }
920 }
921 
922 
923 void
925  bool ok = true;
926  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
927  SUMOTime frequency = attrs.getSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok);
928  SUMOTime begin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, id.c_str(), ok, -1);
929  std::string edge = attrs.getStringReporting(SUMO_ATTR_EDGE, id.c_str(), ok);
930  std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, id.c_str(), ok);
931  if (!ok) {
932  return;
933  }
934  try {
935  myDetectorBuilder.buildRouteProbe(id, edge, frequency, begin,
937  } catch (InvalidArgument& e) {
938  WRITE_ERROR(e.what());
939  } catch (IOError& e) {
940  WRITE_ERROR(e.what());
941  }
942 }
943 
944 
945 
946 void
948  // check whether this is a detector connected to a tls an optionally to a link
949  bool ok = true;
950  const std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
951  const std::string lsaid = attrs.getOptStringReporting(SUMO_ATTR_TLID, id.c_str(), ok, "<invalid>");
952  const std::string toLane = attrs.getOptStringReporting(SUMO_ATTR_TO, id.c_str(), ok, "<invalid>");
953  const SUMOTime haltingTimeThreshold = attrs.getOptSUMOTimeReporting(SUMO_ATTR_HALTING_TIME_THRESHOLD, id.c_str(), ok, TIME2STEPS(1));
954  const SUMOReal haltingSpeedThreshold = attrs.getOptSUMORealReporting(SUMO_ATTR_HALTING_SPEED_THRESHOLD, id.c_str(), ok, 5.0f / 3.6f);
955  const SUMOReal jamDistThreshold = attrs.getOptSUMORealReporting(SUMO_ATTR_JAM_DIST_THRESHOLD, id.c_str(), ok, 10.0f);
956  const SUMOReal position = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, id.c_str(), ok);
957  const SUMOReal length = attrs.getSUMORealReporting(SUMO_ATTR_LENGTH, id.c_str(), ok);
958  const bool friendlyPos = attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
959  const bool cont = attrs.getOptBoolReporting(SUMO_ATTR_CONT, id.c_str(), ok, false);
960  const std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, id.c_str(), ok);
961  const std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, id.c_str(), ok);
962  if (!ok) {
963  return;
964  }
965  try {
966  if (lsaid != "<invalid>") {
967  if (toLane == "<invalid>") {
968  myDetectorBuilder.buildE2Detector(id, lane, position, length, cont,
971  haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold,
972  friendlyPos);
973  } else {
974  myDetectorBuilder.buildE2Detector(id, lane, position, length, cont,
975  myJunctionControlBuilder.getTLLogic(lsaid), toLane,
977  haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold,
978  friendlyPos);
979  }
980  } else {
981  bool ok = true;
982  SUMOTime frequency = attrs.getSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok);
983  if (!ok) {
984  return;
985  }
986  myDetectorBuilder.buildE2Detector(id, lane, position, length, cont, frequency,
988  haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold,
989  friendlyPos);
990  }
991  } catch (InvalidArgument& e) {
992  WRITE_ERROR(e.what());
993  } catch (IOError& e) {
994  WRITE_ERROR(e.what());
995  }
996 }
997 
998 
999 void
1001  bool ok = true;
1002  // inform the user about deprecated values
1003  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
1007  }
1011  }
1012 
1013  const SUMOTime frequency = attrs.getSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok);
1014  const SUMOTime haltingTimeThreshold = attrs.hasAttribute(SUMO_ATTR_HALTING_TIME_THRESHOLD__DEPRECATED)
1017  const SUMOReal haltingSpeedThreshold = attrs.hasAttribute(SUMO_ATTR_HALTING_SPEED_THRESHOLD__DEPRECATED)
1018  ? attrs.getOptSUMORealReporting(SUMO_ATTR_HALTING_SPEED_THRESHOLD__DEPRECATED, id.c_str(), ok, 5.0f / 3.6f)
1019  : attrs.getOptSUMORealReporting(SUMO_ATTR_HALTING_SPEED_THRESHOLD, id.c_str(), ok, 5.0f / 3.6f);
1020  const std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, id.c_str(), ok);
1021  if (!ok) {
1022  return;
1023  }
1024  try {
1027  frequency, haltingSpeedThreshold, haltingTimeThreshold);
1028  } catch (InvalidArgument& e) {
1029  WRITE_ERROR(e.what());
1030  } catch (IOError& e) {
1031  WRITE_ERROR(e.what());
1032  }
1033 }
1034 
1035 
1036 void
1038  bool ok = true;
1039  const SUMOReal position = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
1040  const bool friendlyPos = attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, myDetectorBuilder.getCurrentE3ID().c_str(), ok, false);
1041  const std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
1042  if (!ok) {
1043  return;
1044  }
1045  myDetectorBuilder.addE3Entry(lane, position, friendlyPos);
1046 }
1047 
1048 
1049 void
1051  bool ok = true;
1052  const SUMOReal position = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
1053  const bool friendlyPos = attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, myDetectorBuilder.getCurrentE3ID().c_str(), ok, false);
1054  const std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
1055  if (!ok) {
1056  return;
1057  }
1058  myDetectorBuilder.addE3Exit(lane, position, friendlyPos);
1059 }
1060 
1061 
1062 void
1063 NLHandler::addEdgeLaneMeanData(const SUMOSAXAttributes& attrs, int objecttype) {
1064  bool ok = true;
1065  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
1066  const SUMOReal maxTravelTime = attrs.getOptSUMORealReporting(SUMO_ATTR_MAX_TRAVELTIME, id.c_str(), ok, 100000);
1067  const SUMOReal minSamples = attrs.getOptSUMORealReporting(SUMO_ATTR_MIN_SAMPLES, id.c_str(), ok, 0);
1068  const SUMOReal haltingSpeedThreshold = attrs.getOptSUMORealReporting(SUMO_ATTR_HALTING_SPEED_THRESHOLD, id.c_str(), ok, POSITION_EPS);
1069  const std::string excludeEmpty = attrs.getOptStringReporting(SUMO_ATTR_EXCLUDE_EMPTY, id.c_str(), ok, "false");
1070  const bool withInternal = attrs.getOptBoolReporting(SUMO_ATTR_WITH_INTERNAL, id.c_str(), ok, false);
1071  const bool trackVehicles = attrs.getOptBoolReporting(SUMO_ATTR_TRACK_VEHICLES, id.c_str(), ok, false);
1072  const std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, id.c_str(), ok);
1073  const std::string type = attrs.getOptStringReporting(SUMO_ATTR_TYPE, id.c_str(), ok, "performance");
1074  std::string vtypes = attrs.getOptStringReporting(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
1076  vtypes = attrs.getStringReporting(SUMO_ATTR_VTYPES__DEPRECATED, id.c_str(), ok);
1078  WRITE_WARNING("'" + toString(SUMO_ATTR_VTYPES__DEPRECATED) + " is deprecated; please use '" + toString(SUMO_ATTR_VTYPES) + "'.");
1080  }
1081  }
1082  const SUMOTime frequency = attrs.getOptSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok, -1);
1083  const SUMOTime begin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, id.c_str(), ok, string2time(OptionsCont::getOptions().getString("begin")));
1084  const SUMOTime end = attrs.getOptSUMOTimeReporting(SUMO_ATTR_END, id.c_str(), ok, string2time(OptionsCont::getOptions().getString("end")));
1085  if (!ok) {
1086  return;
1087  }
1088  try {
1089  myDetectorBuilder.createEdgeLaneMeanData(id, frequency, begin, end,
1090  type, objecttype == SUMO_TAG_MEANDATA_LANE,
1091  // equivalent to TplConvert::_2bool used in SUMOSAXAttributes::getBool
1092  excludeEmpty[0] != 't' && excludeEmpty[0] != 'T' && excludeEmpty[0] != '1' && excludeEmpty[0] != 'x',
1093  excludeEmpty == "defaults", withInternal, trackVehicles,
1094  maxTravelTime, minSamples, haltingSpeedThreshold, vtypes,
1096  } catch (InvalidArgument& e) {
1097  WRITE_ERROR(e.what());
1098  } catch (IOError& e) {
1099  WRITE_ERROR(e.what());
1100  }
1101 }
1102 
1103 
1104 
1105 void
1107  bool ok = true;
1108  std::string id = attrs.getStringReporting(SUMO_ATTR_LANE, 0, ok);
1109  if (!MSGlobals::gUsingInternalLanes && id[0] == ':') {
1111  return;
1112  }
1113  myCurrentIsInternalToSkip = false;
1115 }
1116 
1117 
1118 void
1120  // do not process internal lanes if not wished
1122  return;
1123  }
1124  try {
1125  bool ok = true;
1126  SUMOReal pass = attrs.getOptSUMORealReporting(SUMO_ATTR_PASS, 0, ok, -1);
1127  std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, 0, ok);
1128  std::string dir = attrs.getStringReporting(SUMO_ATTR_DIR, 0, ok);
1129  std::string state = attrs.getStringReporting(SUMO_ATTR_STATE, 0, ok);
1130  std::string tlID = attrs.getOptStringReporting(SUMO_ATTR_TLID, 0, ok, "");
1131 #ifdef HAVE_INTERNAL_LANES
1132  std::string via = attrs.getOptStringReporting(SUMO_ATTR_VIA, 0, ok, "");
1133 #endif
1134  if (!ok) {
1135  return;
1136  }
1137  if (tlID != "") {
1138  int linkNumber = attrs.hasAttribute(SUMO_ATTR_TLLINKINDEX)
1139  ? attrs.getIntReporting(SUMO_ATTR_TLLINKINDEX, 0, ok)
1141  if (!ok) {
1142  return;
1143  }
1145 #ifdef HAVE_INTERNAL_LANES
1146  via, pass,
1147 #endif
1148  parseLinkDir(dir), parseLinkState(state), tlID, linkNumber);
1149  } else {
1151 #ifdef HAVE_INTERNAL_LANES
1152  via, pass,
1153 #endif
1154  parseLinkDir(dir), parseLinkState(state));
1155  }
1156  } catch (InvalidArgument& e) {
1157  WRITE_ERROR(e.what());
1158  }
1159 }
1160 
1161 
1162 
1163 void
1165  bool ok = true;
1166  std::string fromID = attrs.getStringReporting(SUMO_ATTR_FROM, 0, ok);
1167  if (!MSGlobals::gUsingInternalLanes && fromID[0] == ':') {
1168  return;
1169  }
1170 
1171  try {
1172  bool ok = true;
1173  std::string toID = attrs.getStringReporting(SUMO_ATTR_TO, 0, ok);
1174  std::string laneIndices;
1175  if (attrs.hasAttribute(SUMO_ATTR_LANE)) {
1178  WRITE_WARNING("'" + toString(SUMO_ATTR_LANE) + "' is deprecated, please use '" + toString(SUMO_ATTR_FROM_LANE) +
1179  "' and '" + toString(SUMO_ATTR_TO_LANE) + "' instead.");
1180  }
1181  laneIndices = attrs.getStringReporting(SUMO_ATTR_LANE, 0, ok);
1182  } else {
1183  laneIndices = attrs.getStringReporting(SUMO_ATTR_FROM_LANE, 0, ok) + ":" + attrs.getStringReporting(SUMO_ATTR_TO_LANE, 0, ok);
1184  }
1187  std::string tlID = attrs.getOptStringReporting(SUMO_ATTR_TLID, 0, ok, "");
1188 #ifdef HAVE_INTERNAL_LANES
1189  std::string viaID = attrs.getOptStringReporting(SUMO_ATTR_VIA, 0, ok, "");
1190  SUMOReal pass = attrs.getOptSUMORealReporting(SUMO_ATTR_PASS, 0, ok, -1);
1191 #endif
1192 
1193  MSEdge* from = MSEdge::dictionary(fromID);
1194  if (from == 0) {
1195  WRITE_ERROR("Unknown from-edge '" + fromID + "' in connection");
1196  return;
1197  }
1198  MSEdge* to = MSEdge::dictionary(toID);
1199  if (to == 0) {
1200  WRITE_ERROR("Unknown to-edge '" + toID + "' in connection");
1201  return;
1202  }
1203  std::pair<MSLane*, MSLane*> lanes = getLanesFromIndices(from, to, laneIndices, ok);
1204  if (!ok) {
1205  return;
1206  }
1207  MSLane* fromLane = lanes.first;
1208  MSLane* toLane = lanes.second;
1209  assert(fromLane);
1210  assert(toLane);
1211 
1212  int tlLinkIdx;
1213  if (tlID != "") {
1214  tlLinkIdx = attrs.hasAttribute(SUMO_ATTR_TLLINKINDEX)
1215  ? attrs.getIntReporting(SUMO_ATTR_TLLINKINDEX, 0, ok)
1217  // make sure that the index is in range
1219  if (tlLinkIdx >= (int)logic->getCurrentPhaseDef().getState().size()) {
1220  WRITE_ERROR("Invalid " + toString(SUMO_ATTR_TLLINKINDEX) + " '" + toString(tlLinkIdx) +
1221  "' in connection controlled by '" + tlID + "'");
1222  return;
1223  }
1224  if (!ok) {
1225  return;
1226  }
1227  }
1228  SUMOReal length = fromLane->getShape()[-1].distanceTo(toLane->getShape()[0]);
1229  MSLink* link = 0;
1230 
1231  // build the link
1232 #ifdef HAVE_INTERNAL_LANES
1233  MSLane* via = 0;
1234  if (viaID != "" && MSGlobals::gUsingInternalLanes) {
1235  via = MSLane::dictionary(viaID);
1236  if (via == 0) {
1237  WRITE_ERROR("An unknown lane ('" + viaID +
1238  "') should be set as a via-lane for lane '" + toLane->getID() + "'.");
1239  return;
1240  }
1241  length = via->getLength();
1242  }
1243  if (pass >= 0) {
1244  static_cast<MSInternalLane*>(toLane)->setPassPosition(pass);
1245  }
1246  link = new MSLink(toLane, via, dir, state, length);
1247  if (via != 0) {
1248  via->addIncomingLane(fromLane, link);
1249  } else {
1250  toLane->addIncomingLane(fromLane, link);
1251  }
1252 #else
1253  link = new MSLink(toLane, dir, state, length);
1254  toLane->addIncomingLane(fromLane, link);
1255 #endif
1256  toLane->addApproachingLane(fromLane);
1257 
1258  // if a traffic light is responsible for it, inform the traffic light
1259  // check whether this link is controlled by a traffic light
1260  if (tlID != "") {
1262  logics.addLink(link, fromLane, tlLinkIdx);
1263  }
1264  // add the link
1265  fromLane->addLink(link);
1266 
1267  } catch (InvalidArgument& e) {
1268  WRITE_ERROR(e.what());
1269  }
1270 }
1271 
1272 
1274 NLHandler::parseLinkDir(const std::string& dir) {
1275  if (SUMOXMLDefinitions::LinkDirections.hasString(dir)) {
1277  } else {
1278  throw InvalidArgument("Unrecognised link direction '" + dir + "'.");
1279  }
1280 }
1281 
1282 
1283 LinkState
1284 NLHandler::parseLinkState(const std::string& state) {
1285  if (SUMOXMLDefinitions::LinkStates.hasString(state)) {
1286  return SUMOXMLDefinitions::LinkStates.get(state);
1287  } else {
1288  if (state == "t") { // legacy networks
1289  // WRITE_WARNING("Obsolete link state 't'. Use 'o' instead");
1291  } else {
1292  throw InvalidArgument("Unrecognised link state '" + state + "'.");
1293  }
1294  }
1295 }
1296 
1297 
1298 std::pair<MSLane*, MSLane*>
1299 NLHandler::getLanesFromIndices(MSEdge* from, MSEdge* to, const std::string& laneIndices, bool& ok) {
1300  std::string error = "Invalid attribute in connection from '" + from->getID() + "' to '" + to->getID() + "' ";
1301  StringTokenizer st(laneIndices, ':');
1302  if (st.size() == 2) {
1303  int fromLaneIdx;
1304  int toLaneIdx;
1305  try {
1306  fromLaneIdx = TplConvertSec<char>::_2intSec(st.next().c_str(), -1);
1307  toLaneIdx = TplConvertSec<char>::_2intSec(st.next().c_str(), -1);
1308  if (fromLaneIdx >= 0 && static_cast<unsigned int>(fromLaneIdx) < from->getLanes().size() &&
1309  toLaneIdx >= 0 && static_cast<unsigned int>(toLaneIdx) < to->getLanes().size()) {
1310  return std::pair<MSLane*, MSLane*>(from->getLanes()[fromLaneIdx], to->getLanes()[toLaneIdx]);
1311  } else {
1312  error += "(invalid index)";
1313  }
1314  } catch (NumberFormatException&) {
1315  error += "(number format)";
1316  }
1317  } else {
1318  error += "(malformed)";
1319  }
1320  WRITE_ERROR(error);
1321  ok = false;
1322  return std::pair<MSLane*, MSLane*>(static_cast<MSLane*>(0), static_cast<MSLane*>(0));
1323 }
1324 
1325 
1326 // ----------------------------------
1327 void
1329  bool ok = true;
1332  attrs.getObjectType(), 0, ok, false);
1335  attrs.getObjectType(), 0, ok);
1338  attrs.getObjectType(), 0, ok);
1339  std::string proj = attrs.getStringReporting(SUMO_ATTR_ORIG_PROJ, 0, ok);
1340  if (ok) {
1341  Position networkOffset = s[0];
1342  GeoConvHelper::init(proj, networkOffset, origBoundary, convBoundary);
1343  }
1344 }
1345 
1346 
1347 void
1349  bool ok = true;
1350  myCurrentIsBroken = false;
1351  // get the id, report an error if not given or empty...
1353  if (!ok) {
1354  myCurrentIsBroken = true;
1355  return;
1356  }
1357  try {
1359  if (!MSEdge::dictionary(myCurrentDistrictID + "-sink", sink)) {
1360  delete sink;
1361  throw InvalidArgument("Another edge with the id '" + myCurrentDistrictID + "-sink' exists.");
1362  }
1363  sink->initialize(new std::vector<MSLane*>(), MSEdge::EDGEFUNCTION_DISTRICT);
1365  if (!MSEdge::dictionary(myCurrentDistrictID + "-source", source)) {
1366  delete source;
1367  throw InvalidArgument("Another edge with the id '" + myCurrentDistrictID + "-source' exists.");
1368  }
1369  source->initialize(new std::vector<MSLane*>(), MSEdge::EDGEFUNCTION_DISTRICT);
1370  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
1371  std::vector<std::string> desc = StringTokenizer(attrs.getString(SUMO_ATTR_EDGES)).getVector();
1372  for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
1373  MSEdge* edge = MSEdge::dictionary(*i);
1374  // check whether the edge exists
1375  if (edge == 0) {
1376  throw InvalidArgument("The edge '" + *i + "' within district '" + myCurrentDistrictID + "' is not known.");
1377  }
1378  source->addFollower(edge);
1379  edge->addFollower(sink);
1380  }
1381  }
1382  } catch (InvalidArgument& e) {
1383  WRITE_ERROR(e.what());
1384  myCurrentIsBroken = true;
1385  }
1386 }
1387 
1388 
1389 void
1390 NLHandler::addDistrictEdge(const SUMOSAXAttributes& attrs, bool isSource) {
1391  if (myCurrentIsBroken) {
1392  // earlier error
1393  return;
1394  }
1395  bool ok = true;
1396  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, myCurrentDistrictID.c_str(), ok);
1397  MSEdge* succ = MSEdge::dictionary(id);
1398  if (succ != 0) {
1399  // connect edge
1400  if (isSource) {
1401  MSEdge::dictionary(myCurrentDistrictID + "-source")->addFollower(succ);
1402  } else {
1404  }
1405  } else {
1406  WRITE_ERROR("At district '" + myCurrentDistrictID + "': succeeding edge '" + id + "' does not exist.");
1407  }
1408 }
1409 
1410 
1411 // ----------------------------------
1412 
1413 
1414 void
1416  // do not process internal lanes if not wished
1418  return;
1419  }
1420  try {
1422  } catch (InvalidArgument& e) {
1423  WRITE_ERROR(e.what());
1424  }
1425 }
1426 
1427 
1428 void
1430  try {
1432  } catch (InvalidArgument& e) {
1433  WRITE_ERROR(e.what());
1434  }
1435 }
1436 
1437 
1438 void
1440  if (!myCurrentIsBroken) {
1441  try {
1443  } catch (InvalidArgument& e) {
1444  WRITE_ERROR(e.what());
1445  myCurrentIsBroken = true;
1446  }
1447  }
1448  myCurrentWAUTID = "";
1449 }
1450 
1451 
1452 /****************************************************************************/