Eclipse SUMO - Simulation of Urban MObility
NLHandler.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
23 // The XML-Handler for network loading
24 /****************************************************************************/
25 #include <config.h>
26 
27 #include <string>
28 #include "NLHandler.h"
29 #include "NLEdgeControlBuilder.h"
31 #include "NLDetectorBuilder.h"
32 #include "NLTriggerBuilder.h"
36 #include <utils/common/SUMOTime.h>
39 #include <utils/common/RGBColor.h>
41 #include <microsim/MSGlobals.h>
42 #include <microsim/MSLane.h>
43 #include <microsim/MSJunction.h>
49 #include <mesosim/MESegment.h>
54 #include <utils/shapes/Shape.h>
55 
56 
57 // ===========================================================================
58 // method definitions
59 // ===========================================================================
60 NLHandler::NLHandler(const std::string& file, MSNet& net,
61  NLDetectorBuilder& detBuilder,
62  NLTriggerBuilder& triggerBuilder,
63  NLEdgeControlBuilder& edgeBuilder,
64  NLJunctionControlBuilder& junctionBuilder) :
65  MSRouteHandler(file, true),
66  myNet(net), myActionBuilder(net),
67  myCurrentIsInternalToSkip(false),
68  myDetectorBuilder(detBuilder), myTriggerBuilder(triggerBuilder),
69  myEdgeControlBuilder(edgeBuilder), myJunctionControlBuilder(junctionBuilder),
70  myAmParsingTLLogicOrJunction(false), myCurrentIsBroken(false),
71  myHaveWarnedAboutInvalidTLType(false),
72  myHaveSeenInternalEdge(false),
73  myHaveJunctionHigherSpeeds(false),
74  myHaveSeenDefaultLength(false),
75  myHaveSeenNeighs(false),
76  myHaveSeenAdditionalSpeedRestrictions(false),
77  myHaveSeenMesoEdgeType(false),
78  myNetworkVersion(0, 0),
79  myNetIsLoaded(false) {
80 }
81 
82 
84 
85 
86 void
88  const SUMOSAXAttributes& attrs) {
89  try {
90  switch (element) {
91  case SUMO_TAG_NET: {
92  bool ok;
93  MSGlobals::gLefthand = attrs.getOpt<bool>(SUMO_ATTR_LEFTHAND, nullptr, ok, false);
94  myHaveJunctionHigherSpeeds = attrs.getOpt<bool>(SUMO_ATTR_HIGHER_SPEED, nullptr, ok, false);
95  myNetworkVersion = StringUtils::toVersion(attrs.get<std::string>(SUMO_ATTR_VERSION, nullptr, ok, false));
96  break;
97  }
98  case SUMO_TAG_EDGE:
99  beginEdgeParsing(attrs);
100  break;
101  case SUMO_TAG_LANE:
102  addLane(attrs);
103  break;
104  case SUMO_TAG_NEIGH:
107  }
108  myHaveSeenNeighs = true;
109  break;
110  case SUMO_TAG_JUNCTION:
111  openJunction(attrs);
112  initJunctionLogic(attrs);
113  break;
114  case SUMO_TAG_PHASE:
115  addPhase(attrs);
116  break;
117  case SUMO_TAG_CONDITION:
118  addCondition(attrs);
119  break;
120  case SUMO_TAG_ASSIGNMENT:
121  addAssignment(attrs);
122  break;
123  case SUMO_TAG_FUNCTION:
124  addFunction(attrs);
125  break;
126  case SUMO_TAG_CONNECTION:
127  addConnection(attrs);
128  break;
129  case SUMO_TAG_CONFLICT:
130  addConflict(attrs);
131  break;
132  case SUMO_TAG_TLLOGIC:
133  initTrafficLightLogic(attrs);
134  break;
135  case SUMO_TAG_REQUEST:
136  addRequest(attrs);
137  break;
138  case SUMO_TAG_WAUT:
139  openWAUT(attrs);
140  break;
142  addWAUTSwitch(attrs);
143  break;
145  addWAUTJunction(attrs);
146  break;
147  case SUMO_TAG_E1DETECTOR:
149  addE1Detector(attrs);
150  break;
151  case SUMO_TAG_E2DETECTOR:
153  addE2Detector(attrs);
154  break;
155  case SUMO_TAG_E3DETECTOR:
157  beginE3Detector(attrs);
158  break;
159  case SUMO_TAG_DET_ENTRY:
160  addE3Entry(attrs);
161  break;
162  case SUMO_TAG_DET_EXIT:
163  addE3Exit(attrs);
164  break;
166  addInstantE1Detector(attrs);
167  break;
168  case SUMO_TAG_VSS:
170  break;
171  case SUMO_TAG_CALIBRATOR:
173  break;
174  case SUMO_TAG_REROUTER:
176  break;
177  case SUMO_TAG_BUS_STOP:
178  case SUMO_TAG_TRAIN_STOP:
182  break;
185  break;
189  break;
190  case SUMO_TAG_ACCESS:
192  break;
196  break;
199  break;
202  break;
205  break;
208  break;
209  case SUMO_TAG_VTYPEPROBE:
210  addVTypeProbeDetector(attrs);
211  break;
212  case SUMO_TAG_ROUTEPROBE:
213  addRouteProbeDetector(attrs);
214  break;
217  break;
220  break;
221  case SUMO_TAG_TIMEDEVENT:
223  break;
224  case SUMO_TAG_VAPORIZER:
226  break;
227  case SUMO_TAG_LOCATION:
228  setLocation(attrs);
229  break;
230  case SUMO_TAG_TAZ:
231  addDistrict(attrs);
232  break;
233  case SUMO_TAG_TAZSOURCE:
234  addDistrictEdge(attrs, true);
235  break;
236  case SUMO_TAG_TAZSINK:
237  addDistrictEdge(attrs, false);
238  break;
239  case SUMO_TAG_ROUNDABOUT:
240  addRoundabout(attrs);
241  break;
242  case SUMO_TAG_TYPE: {
243  bool ok = true;
244  myCurrentTypeID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
245  break;
246  }
247  case SUMO_TAG_RESTRICTION: {
248  bool ok = true;
249  const SUMOVehicleClass svc = getVehicleClassID(attrs.get<std::string>(SUMO_ATTR_VCLASS, myCurrentTypeID.c_str(), ok));
250  const double speed = attrs.get<double>(SUMO_ATTR_SPEED, myCurrentTypeID.c_str(), ok);
251  if (ok) {
252  myNet.addRestriction(myCurrentTypeID, svc, speed);
253  }
254  if (myNetIsLoaded) {
256  }
257  break;
258  }
259  case SUMO_TAG_MESO: {
260  addMesoEdgeType(attrs);
261  break;
262  }
263  case SUMO_TAG_STOPOFFSET: {
264  bool ok = true;
265  const StopOffset stopOffset(attrs, ok);
266  if (!ok) {
268  } else {
270  }
271  break;
272  }
274  bool ok = true;
275  const std::string signalID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
276  if (!MSNet::getInstance()->getTLSControl().knows(signalID)) {
277  throw InvalidArgument("Rail signal '" + signalID + "' in railSignalConstraints is not known");
278  }
280  if (myConstrainedSignal == nullptr) {
281  throw InvalidArgument("Traffic light '" + signalID + "' is not a rail signal");
282  }
283  break;
284  }
285  case SUMO_TAG_PREDECESSOR: // intended fall-through
286  case SUMO_TAG_FOE_INSERTION: // intended fall-through
287  case SUMO_TAG_INSERTION_PREDECESSOR: // intended fall-through
288  case SUMO_TAG_INSERTION_ORDER: // intended fall-through
291  break;
292  default:
293  break;
294  }
295  } catch (InvalidArgument& e) {
296  myCurrentIsBroken = true;
297  WRITE_ERROR(e.what());
298  }
299  MSRouteHandler::myStartElement(element, attrs);
300  if (element == SUMO_TAG_PARAM && !myCurrentIsBroken) {
301  addParam(attrs);
302  }
303 }
304 
305 
306 void
308  switch (element) {
309  case SUMO_TAG_EDGE:
310  closeEdge();
311  break;
312  case SUMO_TAG_LANE:
315  myLastParameterised.pop_back();
316  }
317  break;
318  case SUMO_TAG_JUNCTION:
319  if (!myCurrentIsBroken) {
320  try {
322  } catch (InvalidArgument& e) {
323  WRITE_ERROR(e.what());
324  }
325  }
327  break;
328  case SUMO_TAG_TLLOGIC:
329  if (!myCurrentIsBroken) {
330  try {
332  } catch (InvalidArgument& e) {
334  delete phase;
335  }
336  WRITE_ERROR(e.what());
337  }
338  }
340  break;
341  case SUMO_TAG_FUNCTION:
342  closeFunction();
343  break;
344  case SUMO_TAG_WAUT:
345  closeWAUT();
346  break;
348  myConstrainedSignal = nullptr;
349  break;
350  case SUMO_TAG_E1DETECTOR:
353  case SUMO_TAG_E2DETECTOR:
355  if (!myCurrentIsBroken) {
356  myLastParameterised.pop_back();
357  }
358  break;
359  case SUMO_TAG_E3DETECTOR:
361  endE3Detector();
362  if (!myCurrentIsBroken) {
363  myLastParameterised.pop_back();
364  }
365  break;
369  myLastParameterised.pop_back();
370  break;
371  case SUMO_TAG_BUS_STOP:
372  case SUMO_TAG_TRAIN_STOP:
376  myLastParameterised.pop_back();
377  break;
378  case SUMO_TAG_PREDECESSOR: // intended fall-through
379  case SUMO_TAG_FOE_INSERTION: // intended fall-through
380  case SUMO_TAG_INSERTION_PREDECESSOR: // intended fall-through
381  case SUMO_TAG_INSERTION_ORDER: // intended fall-through
383  myLastParameterised.pop_back();
384  break;
385  case SUMO_TAG_NET:
386  // build junction graph
387  for (JunctionGraph::iterator it = myJunctionGraph.begin(); it != myJunctionGraph.end(); ++it) {
388  MSEdge* edge = MSEdge::dictionary(it->first);
389  MSJunction* from = myJunctionControlBuilder.retrieve(it->second.first);
390  MSJunction* to = myJunctionControlBuilder.retrieve(it->second.second);
391  if (from == nullptr) {
392  WRITE_ERRORF(TL("Unknown from-node '%' for edge '%'."), it->second.first, it->first);
393  return;
394  }
395  if (to == nullptr) {
396  WRITE_ERRORF(TL("Unknown to-node '%' for edge '%'."), it->second.second, it->first);
397  return;
398  }
399  if (edge != nullptr) {
400  edge->setJunctions(from, to);
401  from->addOutgoing(edge);
402  to->addIncoming(edge);
403  }
404  }
405  myNetIsLoaded = true;
406  break;
407  default:
408  break;
409  }
411 }
412 
413 
414 
415 // ---- the root/edge - element
416 void
418  bool ok = true;
419  myCurrentIsBroken = false;
420  // get the id, report an error if not given or empty...
421  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
422  if (!ok) {
423  myCurrentIsBroken = true;
424  return;
425  }
426  // parse the function
428  if (!ok) {
429  myCurrentIsBroken = true;
430  return;
431  }
432  // omit internal edges if not wished
433  if (id[0] == ':') {
434  myHaveSeenInternalEdge = true;
437  return;
438  }
439  std::string junctionID = SUMOXMLDefinitions::getJunctionIDFromInternalEdge(id);
440  myJunctionGraph[id] = std::make_pair(junctionID, junctionID);
441  } else {
443  myJunctionGraph[id] = std::make_pair(
444  attrs.get<std::string>(SUMO_ATTR_FROM, id.c_str(), ok),
445  attrs.get<std::string>(SUMO_ATTR_TO, id.c_str(), ok));
446  }
447  if (!ok) {
448  myCurrentIsBroken = true;
449  return;
450  }
452  // get the street name
453  const std::string streetName = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
454  // get the edge type
455  const std::string edgeType = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
456  // get the edge priority (only for visualization)
457  const int priority = attrs.getOpt<int>(SUMO_ATTR_PRIORITY, id.c_str(), ok, -1); // default taken from netbuild/NBFrame option 'default.priority'
458  // get the bidi-edge
459  const std::string bidi = attrs.getOpt<std::string>(SUMO_ATTR_BIDI, id.c_str(), ok, "");
460  // get the kilometrage/mileage (for visualization and output)
461  const double distance = attrs.getOpt<double>(SUMO_ATTR_DISTANCE, id.c_str(), ok, 0);
462 
463  if (!ok) {
464  myCurrentIsBroken = true;
465  return;
466  }
467  //
468  try {
469  myEdgeControlBuilder.beginEdgeParsing(id, func, streetName, edgeType, priority, bidi, distance);
470  } catch (InvalidArgument& e) {
471  WRITE_ERROR(e.what());
472  myCurrentIsBroken = true;
473  }
474 
475  if (func == SumoXMLEdgeFunc::CROSSING) {
476  //get the crossingEdges attribute (to implement the other side of the road pushbutton)
477  const std::string crossingEdges = attrs.getOpt<std::string>(SUMO_ATTR_CROSSING_EDGES, id.c_str(), ok, "");
478  if (!crossingEdges.empty()) {
479  std::vector<std::string> crossingEdgesVector;
480  StringTokenizer edges(crossingEdges);
481  while (edges.hasNext()) {
482  crossingEdgesVector.push_back(edges.next());
483  }
484  myEdgeControlBuilder.addCrossingEdges(crossingEdgesVector);
485  }
486  }
489 }
490 
491 
492 void
494  myLastParameterised.clear();
495  // omit internal edges if not wished and broken edges
497  return;
498  }
499  try {
501  MSEdge::dictionary(e->getID(), e);
503  } catch (InvalidArgument& e) {
504  WRITE_ERROR(e.what());
505  }
506 }
507 
508 
509 // ---- the root/edge/lanes/lane - element
510 void
512  // omit internal edges if not wished and broken edges
514  return;
515  }
516  bool ok = true;
517  // get the id, report an error if not given or empty...
518  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
519  if (!ok) {
520  myCurrentIsBroken = true;
521  return;
522  }
523  const double maxSpeed = attrs.get<double>(SUMO_ATTR_SPEED, id.c_str(), ok);
524  const double friction = attrs.getOpt<double>(SUMO_ATTR_FRICTION, id.c_str(), ok, (double)(1.), false);
525  const double length = attrs.get<double>(SUMO_ATTR_LENGTH, id.c_str(), ok);
526  const std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, id.c_str(), ok, "", false);
527  const std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
528  const std::string changeLeftS = attrs.getOpt<std::string>(SUMO_ATTR_CHANGE_LEFT, id.c_str(), ok, "");
529  const std::string changeRightS = attrs.getOpt<std::string>(SUMO_ATTR_CHANGE_RIGHT, id.c_str(), ok, "");
530  const double width = attrs.getOpt<double>(SUMO_ATTR_WIDTH, id.c_str(), ok, SUMO_const_laneWidth);
531  const PositionVector shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok);
532  const PositionVector outlineShape = attrs.getOpt<PositionVector>(SUMO_ATTR_OUTLINESHAPE, id.c_str(), ok, PositionVector());
533  const int index = attrs.get<int>(SUMO_ATTR_INDEX, id.c_str(), ok);
534  const bool isRampAccel = attrs.getOpt<bool>(SUMO_ATTR_ACCELERATION, id.c_str(), ok, false);
535  const std::string type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
536  if (shape.size() < 2) {
537  WRITE_ERRORF(TL("Shape of lane '%' is broken.\n Can not build according edge."), id);
538  myCurrentIsBroken = true;
539  return;
540  }
541  const SVCPermissions permissions = parseVehicleClasses(allow, disallow, myNetworkVersion);
542  SVCPermissions changeLeft = parseVehicleClasses(changeLeftS, "", myNetworkVersion);
543  SVCPermissions changeRight = parseVehicleClasses(changeRightS, "", myNetworkVersion);
544  if (MSGlobals::gLefthand) {
545  // internally, changeLeft always checks for the higher lane index
546  // even though the higher lane index is to the right in a left-hand network
547  std::swap(changeLeft, changeRight);
548  }
549  if (permissions != SVCAll || changeLeft != SVCAll || changeRight != SVCAll) {
551  }
552  myCurrentIsBroken |= !ok;
553  if (!myCurrentIsBroken) {
554  try {
555  MSLane* lane = myEdgeControlBuilder.addLane(id, maxSpeed, friction, length, shape, width, permissions, changeLeft, changeRight, index, isRampAccel, type, outlineShape);
556  // insert the lane into the lane-dictionary, checking
557  if (!MSLane::dictionary(id, lane)) {
558  delete lane;
559  WRITE_ERRORF(TL("Another lane with the id '%' exists."), id);
560  myCurrentIsBroken = true;
561  myLastParameterised.push_back(nullptr);
562  } else {
563  myLastParameterised.push_back(lane);
564  }
565  } catch (InvalidArgument& e) {
566  WRITE_ERROR(e.what());
567  }
568  }
569 }
570 
571 
572 // ---- the root/junction - element
573 void
575  myCurrentIsBroken = false;
576  bool ok = true;
577  // get the id, report an error if not given or empty...
578  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
579  if (!ok) {
580  myCurrentIsBroken = true;
581  return;
582  }
583  PositionVector shape;
584  if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
585  // inner junctions have no shape
586  shape = attrs.getOpt<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok, PositionVector());
587  if (shape.size() > 2) {
588  shape.closePolygon();
589  }
590  }
591  double x = attrs.get<double>(SUMO_ATTR_X, id.c_str(), ok);
592  double y = attrs.get<double>(SUMO_ATTR_Y, id.c_str(), ok);
593  double z = attrs.getOpt<double>(SUMO_ATTR_Z, id.c_str(), ok, 0);
594  const SumoXMLNodeType type = attrs.get<SumoXMLNodeType>(SUMO_ATTR_TYPE, id.c_str(), ok);
595  std::string key = attrs.getOpt<std::string>(SUMO_ATTR_KEY, id.c_str(), ok, "");
596  std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
597  // incoming lanes
598  std::vector<MSLane*> incomingLanes;
599  parseLanes(id, attrs.getStringSecure(SUMO_ATTR_INCLANES, ""), incomingLanes, ok);
600  // internal lanes
601  std::vector<MSLane*> internalLanes;
603  parseLanes(id, attrs.getStringSecure(SUMO_ATTR_INTLANES, ""), internalLanes, ok);
604  }
605  if (!ok) {
606  myCurrentIsBroken = true;
607  } else {
608  try {
609  myJunctionControlBuilder.openJunction(id, key, type, Position(x, y, z), shape, incomingLanes, internalLanes, name);
610  } catch (InvalidArgument& e) {
611  WRITE_ERROR(e.what() + std::string("\n Can not build according junction."));
612  myCurrentIsBroken = true;
613  }
614  }
615 }
616 
617 
618 void
619 NLHandler::parseLanes(const std::string& junctionID,
620  const std::string& def, std::vector<MSLane*>& into, bool& ok) {
621  StringTokenizer st(def, " ");
622  while (ok && st.hasNext()) {
623  std::string laneID = st.next();
624  MSLane* lane = MSLane::dictionary(laneID);
625  if (!MSGlobals::gUsingInternalLanes && laneID[0] == ':') {
626  continue;
627  }
628  if (lane == nullptr) {
629  WRITE_ERRORF(TL("An unknown lane ('%') was tried to be set as incoming to junction '%'."), laneID, junctionID);
630  ok = false;
631  continue;
632  }
633  into.push_back(lane);
634  }
635 }
636 // ----
637 
638 void
640  bool ok = true;
641  const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
642  // circumventing empty string test
643  const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
644  if (myLastParameterised.size() > 0 && myLastParameterised.back() != nullptr) {
645  myLastParameterised.back()->setParameter(key, val);
646  }
647  // set
648  if (ok && myAmParsingTLLogicOrJunction) {
649  assert(key != "");
651  }
652 }
653 
654 
655 void
657  myCurrentIsBroken = false;
658  bool ok = true;
659  // get the id, report an error if not given or empty...
660  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
661  if (!ok) {
662  myCurrentIsBroken = true;
663  return;
664  }
665  SUMOTime refTime = attrs.getOptSUMOTimeReporting(SUMO_ATTR_REF_TIME, id.c_str(), ok, 0);
666  SUMOTime period = attrs.getOptSUMOTimeReporting(SUMO_ATTR_PERIOD, id.c_str(), ok, 0);
667  std::string startProg = attrs.get<std::string>(SUMO_ATTR_START_PROG, id.c_str(), ok);
668  if (!ok) {
669  myCurrentIsBroken = true;
670  }
671  if (!myCurrentIsBroken) {
672  myCurrentWAUTID = id;
673  try {
674  myJunctionControlBuilder.getTLLogicControlToUse().addWAUT(refTime, id, startProg, period);
675  } catch (InvalidArgument& e) {
676  WRITE_ERROR(e.what());
677  myCurrentIsBroken = true;
678  }
679  }
680 }
681 
682 
683 void
685  bool ok = true;
687  std::string to = attrs.get<std::string>(SUMO_ATTR_TO, myCurrentWAUTID.c_str(), ok);
688  if (!ok) {
689  myCurrentIsBroken = true;
690  }
691  if (!myCurrentIsBroken) {
692  try {
694  } catch (InvalidArgument& e) {
695  WRITE_ERROR(e.what());
696  myCurrentIsBroken = true;
697  }
698  }
699 }
700 
701 
702 void
704  bool ok = true;
705  std::string wautID = attrs.get<std::string>(SUMO_ATTR_WAUT_ID, nullptr, ok);
706  std::string junctionID = attrs.get<std::string>(SUMO_ATTR_JUNCTION_ID, nullptr, ok);
707  std::string procedure = attrs.getOpt<std::string>(SUMO_ATTR_PROCEDURE, nullptr, ok, "");
708  bool synchron = attrs.getOpt<bool>(SUMO_ATTR_SYNCHRON, nullptr, ok, false);
709  if (!ok) {
710  myCurrentIsBroken = true;
711  }
712  try {
713  if (!myCurrentIsBroken) {
714  myJunctionControlBuilder.getTLLogicControlToUse().addWAUTJunction(wautID, junctionID, procedure, synchron);
715  }
716  } catch (InvalidArgument& e) {
717  WRITE_ERROR(e.what());
718  myCurrentIsBroken = true;
719  }
720 }
721 
722 
723 void
725  if (myCurrentIsBroken) {
726  return;
727  }
728  bool ok = true;
729  int request = attrs.get<int>(SUMO_ATTR_INDEX, nullptr, ok);
730  bool cont = false;
731  cont = attrs.getOpt<bool>(SUMO_ATTR_CONT, nullptr, ok, false);
732  std::string response = attrs.get<std::string>(SUMO_ATTR_RESPONSE, nullptr, ok);
733  std::string foes = attrs.get<std::string>(SUMO_ATTR_FOES, nullptr, ok);
734  if (!ok) {
735  return;
736  }
737  // store received information
738  if (request >= 0 && response.length() > 0) {
739  try {
740  myJunctionControlBuilder.addLogicItem(request, response, foes, cont);
741  } catch (InvalidArgument& e) {
742  WRITE_ERROR(e.what());
743  }
744  }
745 }
746 
747 
748 void
750  if (myCurrentIsBroken) {
751  return;
752  }
754  bool ok = true;
755  // we either a have a junction or a legacy network with ROWLogic
756  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
757  if (ok) {
759  }
760 }
761 
762 
763 void
765  myCurrentIsBroken = false;
767  bool ok = true;
768  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
769  std::string programID = attrs.getOpt<std::string>(SUMO_ATTR_PROGRAMID, id.c_str(), ok, "<unknown>");
771  std::string typeS;
772  if (myJunctionControlBuilder.getTLLogicControlToUse().get(id, programID) == nullptr) {
773  // SUMO_ATTR_TYPE is not needed when only modifying the offset of an
774  // existing program
775  typeS = attrs.get<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok);
776  if (!ok) {
777  myCurrentIsBroken = true;
778  return;
779  }
780  if (SUMOXMLDefinitions::TrafficLightTypes.hasString(typeS)) {
782  } else {
783  WRITE_ERRORF(TL("Traffic light '%' has unknown type '%'."), id, typeS);
784  }
787  WRITE_WARNINGF(TL("Traffic light type '%' cannot be used in mesoscopic simulation. Using '%' as fallback."), toString(type), toString(TrafficLightType::STATIC));
789  }
791  }
792  }
793  //
794  const SUMOTime offset = attrs.getOptSUMOTimeReporting(SUMO_ATTR_OFFSET, id.c_str(), ok, 0);
795  if (!ok) {
796  myCurrentIsBroken = true;
797  return;
798  }
799  myJunctionControlBuilder.initTrafficLightLogic(id, programID, type, offset);
800 }
801 
802 
803 void
805  // try to get the phase definition
806  bool ok = true;
807  const std::string& id = myJunctionControlBuilder.getActiveKey();
809 
811  const std::string state = attrs.get<std::string>(SUMO_ATTR_STATE, nullptr, ok);
812  if (duration == 0) {
813  WRITE_ERROR("Duration of phase " + toString(myJunctionControlBuilder.getLoadedPhases().size())
814  + " for tlLogic '" + myJunctionControlBuilder.getActiveKey()
815  + "' program '" + myJunctionControlBuilder.getActiveSubKey() + "' is zero.");
816  return;
817  }
818  if (!ok) {
819  return;
820  }
821  MSPhaseDefinition* phase = new MSPhaseDefinition(duration, state);
822 
823  // if the traffic light is an actuated traffic light, try to get
824  // the minimum and maximum durations
825  phase->minDuration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MINDURATION, id.c_str(), ok, duration);
826  // if minDur is set but not maxDur, assume high maxDur (avoid using the absolute max in case we do some arithmetic later)
827  SUMOTime defaultMaxDur = attrs.hasAttribute(SUMO_ATTR_MINDURATION) ? std::numeric_limits<int>::max() : duration;
828  phase->maxDuration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MAXDURATION, id.c_str(), ok, defaultMaxDur);
829  phase->earliestEnd = attrs.getOptSUMOTimeReporting(SUMO_ATTR_EARLIEST_END, id.c_str(), ok, tDefault);
830  phase->latestEnd = attrs.getOptSUMOTimeReporting(SUMO_ATTR_LATEST_END, id.c_str(), ok, tDefault);
831  phase->nextPhases = attrs.getOpt<std::vector<int> >(SUMO_ATTR_NEXT, id.c_str(), ok);
832  phase->earlyTarget = attrs.getOpt<std::string>(SUMO_ATTR_EARLY_TARGET, id.c_str(), ok);
833  phase->finalTarget = attrs.getOpt<std::string>(SUMO_ATTR_FINAL_TARGET, id.c_str(), ok);
834  phase->name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok);
835 
836  phase->vehext = attrs.getOptSUMOTimeReporting(SUMO_ATTR_VEHICLEEXTENSION, id.c_str(), ok, tDefault);
837  phase->yellow = attrs.getOptSUMOTimeReporting(SUMO_ATTR_YELLOW, id.c_str(), ok, tDefault);
838  phase->red = attrs.getOptSUMOTimeReporting(SUMO_ATTR_RED, id.c_str(), ok, tDefault);
839 
840  if (attrs.hasAttribute(SUMO_ATTR_TYPE)) {
841  //SOTL attributes
842  //If the type attribute is not present, the parsed phase is of type "undefined" (MSPhaseDefinition constructor),
843  //in this way SOTL traffic light logic can recognize the phase as unsuitable or decides other
844  //behaviors. See SOTL traffic light logic implementations.
845  std::string phaseTypeString;
846  try {
847  phaseTypeString = attrs.get<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, false);
848  } catch (EmptyData&) {
849  MsgHandler::getWarningInstance()->inform("Empty type definition. Assuming phase type as SUMOSOTL_TagAttrDefinitions::SOTL_ATTL_TYPE_TRANSIENT");
850  phase->myTransientNotDecisional = false;
851  }
852  if (phaseTypeString.find("decisional") != std::string::npos) {
853  phase->myTransientNotDecisional = false;
854  } else if (phaseTypeString.find("transient") != std::string::npos) {
855  phase->myTransientNotDecisional = true;
856  } else {
857  MsgHandler::getWarningInstance()->inform("SOTL_ATTL_TYPE_DECISIONAL nor SOTL_ATTL_TYPE_TRANSIENT. Assuming phase type as SUMOSOTL_TagAttrDefinitions::SOTL_ATTL_TYPE_TRANSIENT");
858  phase->myTransientNotDecisional = false;
859  }
860  phase->myCommit = (phaseTypeString.find("commit") != std::string::npos);
861 
862  if (phaseTypeString.find("target") != std::string::npos) {
863  std::string delimiter(" ,;");
864  //Phase declared as target, getting targetLanes attribute
865  try {
867  } catch (EmptyData&) {
868  MsgHandler::getErrorInstance()->inform("Missing targetLane definition for the target phase.");
869  delete phase;
870  return;
871  }
872  }
873  }
874 
875  if (phase->maxDuration < phase->minDuration) {
876  WRITE_WARNINGF(TL("maxDur % should not be smaller than minDir % in phase of tlLogic %"), phase->maxDuration, phase->minDuration, id);
877  phase->maxDuration = phase->duration;
878  }
879 
880  phase->myLastSwitch = string2time(OptionsCont::getOptions().getString("begin")) - 1; // SUMOTime-option
882 }
883 
884 
885 void
887  bool ok = true;
888  const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
889  const std::string value = attrs.get<std::string>(SUMO_ATTR_VALUE, id.c_str(), ok);
890  if (!myJunctionControlBuilder.addCondition(id, value)) {
891  WRITE_ERRORF(TL("Duplicate condition '%' in tlLogic '%'"), id, myJunctionControlBuilder.getActiveKey());
892  }
893 }
894 
895 
896 void
898  bool ok = true;
899  const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
900  const std::string check = attrs.get<std::string>(SUMO_ATTR_CHECK, nullptr, ok);
901  const std::string value = attrs.get<std::string>(SUMO_ATTR_VALUE, id.c_str(), ok);
902  myJunctionControlBuilder.addAssignment(id, check, value);
903 }
904 
905 
906 void
908  bool ok = true;
909  const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
910  const int nArgs = attrs.get<int>(SUMO_ATTR_NARGS, nullptr, ok);
912 }
913 
914 void
917 }
918 
919 void
921  myCurrentIsBroken = false;
922  bool ok = true;
923  // get the id, report an error if not given or empty...
924  const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
925  if (!ok) {
926  myCurrentIsBroken = true;
927  return;
928  }
929  const SUMOTime period = attrs.getOptPeriod(id.c_str(), ok, SUMOTime_MAX_PERIOD);
930  const double position = attrs.get<double>(SUMO_ATTR_POSITION, id.c_str(), ok);
931  const double length = attrs.getOpt<double>(SUMO_ATTR_LENGTH, id.c_str(), ok, 0);
932  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
933  const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
934  const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
935  const std::string nextEdges = attrs.getOpt<std::string>(SUMO_ATTR_NEXT_EDGES, id.c_str(), ok, "");
936  const std::string lane = attrs.get<std::string>(SUMO_ATTR_LANE, id.c_str(), ok);
937  const std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
938  const std::string detectPersonsString = attrs.getOpt<std::string>(SUMO_ATTR_DETECT_PERSONS, id.c_str(), ok, "");
939  int detectPersons = 0;
940  for (std::string mode : StringTokenizer(detectPersonsString).getVector()) {
941  if (SUMOXMLDefinitions::PersonModeValues.hasString(mode)) {
942  detectPersons |= (int)SUMOXMLDefinitions::PersonModeValues.get(mode);
943  } else {
944  WRITE_ERRORF(TL("Invalid person mode '%' in E1 detector definition '%'"), mode, id);
945  myCurrentIsBroken = true;
946  return;
947  }
948  }
949  if (!ok) {
950  myCurrentIsBroken = true;
951  return;
952  }
953  try {
954  Parameterised* det = myDetectorBuilder.buildInductLoop(id, lane, position, length, period,
956  friendlyPos, name, vTypes, nextEdges, detectPersons);
957  myLastParameterised.push_back(det);
958  } catch (InvalidArgument& e) {
959  myCurrentIsBroken = true;
960  WRITE_ERROR(e.what());
961  } catch (IOError& e) {
962  myCurrentIsBroken = true;
963  WRITE_ERROR(e.what());
964  }
965 }
966 
967 
968 void
970  myCurrentIsBroken = false;
971  bool ok = true;
972  // get the id, report an error if not given or empty...
973  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
974  if (!ok) {
975  myCurrentIsBroken = true;
976  return;
977  }
978  const double position = attrs.get<double>(SUMO_ATTR_POSITION, id.c_str(), ok);
979  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
980  const std::string lane = attrs.get<std::string>(SUMO_ATTR_LANE, id.c_str(), ok);
981  const std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
982  const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
983  const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
984  const std::string nextEdges = attrs.getOpt<std::string>(SUMO_ATTR_NEXT_EDGES, id.c_str(), ok, "");
985  if (!ok) {
986  myCurrentIsBroken = true;
987  return;
988  }
989  try {
990  Parameterised* det = myDetectorBuilder.buildInstantInductLoop(id, lane, position, FileHelpers::checkForRelativity(file, getFileName()), friendlyPos, name, vTypes, nextEdges);
991  myLastParameterised.push_back(det);
992  } catch (InvalidArgument& e) {
993  WRITE_ERROR(e.what());
994  } catch (IOError& e) {
995  WRITE_ERROR(e.what());
996  }
997  myCurrentIsBroken = true;
998 }
999 
1000 
1001 void
1003  WRITE_WARNING(TL("VTypeProbes are deprecated. Use fcd-output devices (assigned to the vType) instead."));
1004  bool ok = true;
1005  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1006  SUMOTime period = attrs.getOptPeriod(id.c_str(), ok, SUMOTime_MAX_PERIOD);
1007  std::string type = attrs.getStringSecure(SUMO_ATTR_TYPE, "");
1008  std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1009  if (!ok) {
1010  return;
1011  }
1012  try {
1014  } catch (InvalidArgument& e) {
1015  WRITE_ERROR(e.what());
1016  } catch (IOError& e) {
1017  WRITE_ERROR(e.what());
1018  }
1019 }
1020 
1021 
1022 void
1024  bool ok = true;
1025  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1026  SUMOTime period = attrs.getOptPeriod(id.c_str(), ok, SUMOTime_MAX_PERIOD);
1027  SUMOTime begin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, id.c_str(), ok, -1);
1028  std::string edge = attrs.get<std::string>(SUMO_ATTR_EDGE, id.c_str(), ok);
1029  std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1030  const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
1031  if (!ok) {
1032  return;
1033  }
1034  try {
1035  myDetectorBuilder.buildRouteProbe(id, edge, period, begin,
1036  FileHelpers::checkForRelativity(file, getFileName()), vTypes);
1037  } catch (InvalidArgument& e) {
1038  WRITE_ERROR(e.what());
1039  } catch (IOError& e) {
1040  WRITE_ERROR(e.what());
1041  }
1042 }
1043 
1044 
1045 
1046 void
1048  myCurrentIsBroken = false;
1049  // check whether this is a detector connected to a tls and optionally to a link
1050  bool ok = true;
1051  const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1052  const std::string lsaid = attrs.getOpt<std::string>(SUMO_ATTR_TLID, id.c_str(), ok, "");
1053  const std::string toLane = attrs.getOpt<std::string>(SUMO_ATTR_TO, id.c_str(), ok, "");
1054  const SUMOTime haltingTimeThreshold = attrs.getOptSUMOTimeReporting(SUMO_ATTR_HALTING_TIME_THRESHOLD, id.c_str(), ok, TIME2STEPS(1));
1055  const double haltingSpeedThreshold = attrs.getOpt<double>(SUMO_ATTR_HALTING_SPEED_THRESHOLD, id.c_str(), ok, 5.0f / 3.6f);
1056  const double jamDistThreshold = attrs.getOpt<double>(SUMO_ATTR_JAM_DIST_THRESHOLD, id.c_str(), ok, 10.0f);
1057  double position = attrs.getOpt<double>(SUMO_ATTR_POSITION, id.c_str(), ok, std::numeric_limits<double>::max());
1058  const double length = attrs.getOpt<double>(SUMO_ATTR_LENGTH, id.c_str(), ok, std::numeric_limits<double>::max());
1059  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
1060  const bool showDetector = attrs.getOpt<bool>(SUMO_ATTR_SHOW_DETECTOR, id.c_str(), ok, true);
1061  const std::string contStr = attrs.getOpt<std::string>(SUMO_ATTR_CONT, id.c_str(), ok, "");
1062  if (contStr != "") {
1063  WRITE_WARNINGF(TL("Ignoring deprecated argument 'cont' for E2 detector '%'"), id);
1064  }
1065  std::string lane = attrs.getOpt<std::string>(SUMO_ATTR_LANE, id.c_str(), ok, "");
1066  const std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1067  const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
1068  const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
1069  const std::string nextEdges = attrs.getOpt<std::string>(SUMO_ATTR_NEXT_EDGES, id.c_str(), ok, "");
1070 
1071  double endPosition = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, id.c_str(), ok, std::numeric_limits<double>::max());
1072  const std::string lanes = attrs.getOpt<std::string>(SUMO_ATTR_LANES, id.c_str(), ok, ""); // lanes has priority to lane
1073  const std::string detectPersonsString = attrs.getOpt<std::string>(SUMO_ATTR_DETECT_PERSONS, id.c_str(), ok, "");
1074  int detectPersons = 0;
1075  for (std::string mode : StringTokenizer(detectPersonsString).getVector()) {
1076  if (SUMOXMLDefinitions::PersonModeValues.hasString(mode)) {
1077  detectPersons |= (int)SUMOXMLDefinitions::PersonModeValues.get(mode);
1078  } else {
1079  WRITE_ERRORF(TL("Invalid person mode '%' in E2 detector definition '%'"), mode, id);
1080  myCurrentIsBroken = true;
1081  return;
1082  }
1083  }
1084  if (!ok) {
1085  myCurrentIsBroken = true;
1086  return;
1087  }
1088 
1089  bool lanesGiven = lanes != "";
1090  bool laneGiven = lane != "";
1091  if (!(lanesGiven || laneGiven)) {
1092  // in absence of any lane-specification assume specification by id
1093  WRITE_WARNING(TL("Trying to specify detector's lane by the given id since the argument 'lane' is missing."))
1094  lane = id;
1095  laneGiven = true;
1096  }
1097  bool lengthGiven = length != std::numeric_limits<double>::max();
1098  bool posGiven = position != std::numeric_limits<double>::max();
1099  bool endPosGiven = endPosition != std::numeric_limits<double>::max();
1100  bool lsaGiven = lsaid != "";
1101  bool toLaneGiven = toLane != "";
1102 
1103  MSLane* clane = nullptr;
1104  std::vector<MSLane*> clanes;
1105  if (lanesGiven) {
1106  // If lanes is given, endPos and startPos are required. lane, and length are ignored
1107  std::string seps = " ,\t\n";
1108  StringTokenizer st = StringTokenizer(lanes, seps, true);
1109 // std::cout << "Parsing lanes..." << std::endl;
1110  while (st.hasNext()) {
1111  std::string nextLaneID = st.next();
1112 // std::cout << "Next: " << nextLaneID << std::endl;
1113  if (nextLaneID.find_first_of(seps) != nextLaneID.npos) {
1114  continue;
1115  }
1116  clane = myDetectorBuilder.getLaneChecking(nextLaneID, SUMO_TAG_E2DETECTOR, id);
1117  clanes.push_back(clane);
1118  }
1119  if (clanes.size() == 0) {
1120  throw InvalidArgument("Malformed argument 'lanes' for E2Detector '" + id + "'.\nSpecify 'lanes' as a sequence of lane-IDs separated by whitespace or comma (',')");
1121  }
1122  if (laneGiven) {
1123  WRITE_WARNING("Ignoring argument 'lane' for E2Detector '" + id + "' since argument 'lanes' was given.\n"
1124  "Usage combinations for positional specification: [lane, pos, length], [lane, endPos, length], or [lanes, pos, endPos]");
1125  }
1126  if (lengthGiven) {
1127  WRITE_WARNING("Ignoring argument 'length' for E2Detector '" + id + "' since argument 'lanes' was given.\n"
1128  "Usage combinations for positional specification: [lane, pos, length], [lane, endPos, length], or [lanes, pos, endPos]");
1129  }
1130  if (!posGiven) {
1131  // assuming start pos == lane start
1132  position = 0;
1133  WRITE_WARNINGF(TL("Missing argument 'pos' for E2Detector '%'. Assuming detector start == lane start of lane '%'."), id, clanes[0]->getID());
1134  }
1135  if (!endPosGiven) {
1136  // assuming end pos == lane end
1137  endPosition = clanes[clanes.size() - 1]->getLength();
1138  WRITE_WARNINGF(TL("Missing argument 'endPos' for E2Detector '%'. Assuming detector end == lane end of lane '%'."), id, clanes[clanes.size() - 1]->getID());
1139  }
1140 
1141  } else {
1142  if (!laneGiven) {
1143  std::stringstream ss;
1144  ss << "Missing argument 'lane' for E2Detector '" << id << "'."
1145  << "\nUsage combinations for positional specification: [lane, pos, length], [lane, endPos, length], or [lanes, pos, endPos]";
1146  throw InvalidArgument(ss.str());
1147  }
1149 
1150  if (posGiven) {
1151  // start pos is given
1152  if (endPosGiven && lengthGiven) {
1153  std::stringstream ss;
1154  ss << "Ignoring argument 'endPos' for E2Detector '" << id << "' since argument 'pos' was given."
1155  << "\nUsage combinations for positional specification: [lane, pos, length], [lane, endPos, length], or [lanes, pos, endPos]";
1156  WRITE_WARNING(ss.str());
1157  endPosition = std::numeric_limits<double>::max();
1158  }
1159  if (!lengthGiven && !endPosGiven) {
1160  std::stringstream ss;
1161  ss << "Missing arguments 'length'/'endPos' for E2Detector '" << id << "'. Assuming detector end == lane end of lane '" << lane << "'.";
1162  WRITE_WARNING(ss.str());
1163  endPosition = clane->getLength();
1164  }
1165  } else if (endPosGiven) {
1166  // endPos is given, pos is not given
1167  if (!lengthGiven) {
1168  std::stringstream ss;
1169  ss << "Missing arguments 'length'/'pos' for E2Detector '" << id << "'. Assuming detector start == lane start of lane '" << lane << "'.";
1170  WRITE_WARNING(ss.str());
1171  }
1172  } else {
1173  std::stringstream ss;
1174  if (lengthGiven && fabs(length - clane->getLength()) > NUMERICAL_EPS) {
1175  ss << "Incomplete positional specification for E2Detector '" << id << "'."
1176  << "\nUsage combinations for positional specification: [lane, pos, length], [lane, endPos, length], or [lanes, pos, endPos]";
1177  throw InvalidArgument(ss.str());
1178  }
1179  endPosition = clane->getLength();
1180  position = 0;
1181  ss << "Missing arguments 'pos'/'endPos' for E2Detector '" << id << "'. Assuming that the detector covers the whole lane '" << lane << "'.";
1182  WRITE_WARNING(ss.str());
1183  }
1184  }
1185 
1186  // Period
1187 
1188  SUMOTime period;
1189  if (!lsaGiven) {
1190  period = attrs.getOptPeriod(id.c_str(), ok, SUMOTime_MAX_PERIOD);
1191  if (!ok) {
1192  myCurrentIsBroken = true;
1193  return;
1194  }
1195  } else {
1196  period = attrs.getPeriod(id.c_str(), ok, false);
1197  }
1198 
1199  // TLS
1200  MSTLLogicControl::TLSLogicVariants* tlls = nullptr;
1201  if (lsaGiven) {
1202  tlls = &myJunctionControlBuilder.getTLLogic(lsaid);
1203  if (tlls->getActive() == nullptr) {
1204  throw InvalidArgument("The detector '" + id + "' refers to an unknown lsa '" + lsaid + "'.");
1205  }
1206  if (period != -1) {
1207  WRITE_WARNINGF(TL("Ignoring argument 'period' for E2Detector '%' since argument 'tl' was given."), id);
1208  period = -1;
1209  }
1210  }
1211 
1212  // Link
1213  MSLane* cToLane = nullptr;
1214  if (toLaneGiven) {
1215  cToLane = myDetectorBuilder.getLaneChecking(toLane, SUMO_TAG_E2DETECTOR, id);
1216  }
1217 
1218  // File
1219  std::string filename;
1220  try {
1221  filename = FileHelpers::checkForRelativity(file, getFileName());
1222  } catch (IOError& e) {
1223  WRITE_ERROR(e.what());
1224  }
1225 
1226  Parameterised* det;
1227  // Build detector
1228  if (lanesGiven) {
1229  // specification by a lane sequence
1230  det = myDetectorBuilder.buildE2Detector(id, clanes, position, endPosition, filename, period,
1231  haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold,
1232  name, vTypes, nextEdges, detectPersons, friendlyPos, showDetector,
1233  tlls, cToLane);
1234  } else {
1235  // specification by start or end lane
1236  det = myDetectorBuilder.buildE2Detector(id, clane, position, endPosition, length, filename, period,
1237  haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold,
1238  name, vTypes, nextEdges, detectPersons, friendlyPos, showDetector,
1239  tlls, cToLane);
1240  }
1241  myLastParameterised.push_back(det);
1242 }
1243 
1244 
1245 void
1247  myCurrentIsBroken = false;
1248  bool ok = true;
1249  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1250  const SUMOTime period = attrs.getOptPeriod(id.c_str(), ok, SUMOTime_MAX_PERIOD);
1251  const SUMOTime haltingTimeThreshold = attrs.getOptSUMOTimeReporting(SUMO_ATTR_HALTING_TIME_THRESHOLD, id.c_str(), ok, TIME2STEPS(1));
1252  const double haltingSpeedThreshold = attrs.getOpt<double>(SUMO_ATTR_HALTING_SPEED_THRESHOLD, id.c_str(), ok, 5.0f / 3.6f);
1253  const std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1254  const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
1255  const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
1256  const std::string nextEdges = attrs.getOpt<std::string>(SUMO_ATTR_NEXT_EDGES, id.c_str(), ok, "");
1257  const bool openEntry = attrs.getOpt<bool>(SUMO_ATTR_OPEN_ENTRY, id.c_str(), ok, false);
1258  const bool expectArrival = attrs.getOpt<bool>(SUMO_ATTR_EXPECT_ARRIVAL, id.c_str(), ok, false);
1259  const std::string detectPersonsString = attrs.getOpt<std::string>(SUMO_ATTR_DETECT_PERSONS, id.c_str(), ok, "");
1260  int detectPersons = 0;
1261  for (std::string mode : StringTokenizer(detectPersonsString).getVector()) {
1262  if (SUMOXMLDefinitions::PersonModeValues.hasString(mode)) {
1263  detectPersons |= (int)SUMOXMLDefinitions::PersonModeValues.get(mode);
1264  } else {
1265  WRITE_ERRORF(TL("Invalid person mode '%' in E3 detector definition '%'"), mode, id);
1266  myCurrentIsBroken = true;
1267  return;
1268  }
1269  }
1270  if (!ok) {
1271  myCurrentIsBroken = true;
1272  return;
1273  }
1274  try {
1277  period, haltingSpeedThreshold, haltingTimeThreshold, name, vTypes, nextEdges, detectPersons, openEntry, expectArrival);
1278  myLastParameterised.push_back(det);
1279  } catch (InvalidArgument& e) {
1280  myCurrentIsBroken = true;
1281  WRITE_ERROR(e.what());
1282  } catch (IOError& e) {
1283  myCurrentIsBroken = true;
1284  WRITE_ERROR(e.what());
1285  }
1286 }
1287 
1288 
1289 void
1291  bool ok = true;
1292  const double position = attrs.get<double>(SUMO_ATTR_POSITION, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
1293  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, myDetectorBuilder.getCurrentE3ID().c_str(), ok, false);
1294  const std::string lane = attrs.get<std::string>(SUMO_ATTR_LANE, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
1295  if (!ok) {
1296  return;
1297  }
1298  myDetectorBuilder.addE3Entry(lane, position, friendlyPos);
1299 }
1300 
1301 
1302 void
1304  bool ok = true;
1305  const double position = attrs.get<double>(SUMO_ATTR_POSITION, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
1306  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, myDetectorBuilder.getCurrentE3ID().c_str(), ok, false);
1307  const std::string lane = attrs.get<std::string>(SUMO_ATTR_LANE, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
1308  if (!ok) {
1309  return;
1310  }
1311  myDetectorBuilder.addE3Exit(lane, position, friendlyPos);
1312 }
1313 
1314 
1315 void
1316 NLHandler::addEdgeLaneMeanData(const SUMOSAXAttributes& attrs, int objecttype) {
1317  bool ok = true;
1318  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1319  const double maxTravelTime = attrs.getOpt<double>(SUMO_ATTR_MAX_TRAVELTIME, id.c_str(), ok, 100000);
1320  const double minSamples = attrs.getOpt<double>(SUMO_ATTR_MIN_SAMPLES, id.c_str(), ok, 0);
1321  const double haltingSpeedThreshold = attrs.getOpt<double>(SUMO_ATTR_HALTING_SPEED_THRESHOLD, id.c_str(), ok, POSITION_EPS);
1322  const std::string excludeEmpty = attrs.getOpt<std::string>(SUMO_ATTR_EXCLUDE_EMPTY, id.c_str(), ok, "false");
1323  const bool withInternal = attrs.getOpt<bool>(SUMO_ATTR_WITH_INTERNAL, id.c_str(), ok, false);
1324  const bool trackVehicles = attrs.getOpt<bool>(SUMO_ATTR_TRACK_VEHICLES, id.c_str(), ok, false);
1325  const std::string detectPersonsString = attrs.getOpt<std::string>(SUMO_ATTR_DETECT_PERSONS, id.c_str(), ok, "");
1326  const std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1327  const std::string type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "performance");
1328  std::string vtypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
1329  const std::string writeAttributes = attrs.getOpt<std::string>(SUMO_ATTR_WRITE_ATTRIBUTES, id.c_str(), ok, "");
1330  const SUMOTime period = attrs.getOptPeriod(id.c_str(), ok, -1);
1331  const SUMOTime begin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, id.c_str(), ok, string2time(OptionsCont::getOptions().getString("begin")));
1332  const SUMOTime end = attrs.getOptSUMOTimeReporting(SUMO_ATTR_END, id.c_str(), ok, string2time(OptionsCont::getOptions().getString("end")));
1333  std::vector<std::string> edgeIDs = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_EDGES, id.c_str(), ok);
1334  const std::string edgesFile = attrs.getOpt<std::string>(SUMO_ATTR_EDGESFILE, id.c_str(), ok, "");
1335  const bool aggregate = attrs.getOpt<bool>(SUMO_ATTR_AGGREGATE, id.c_str(), ok, false);
1336  if (!ok) {
1337  return;
1338  }
1339  int detectPersons = 0;
1340  for (std::string mode : StringTokenizer(detectPersonsString).getVector()) {
1341  if (SUMOXMLDefinitions::PersonModeValues.hasString(mode)) {
1342  detectPersons |= (int)SUMOXMLDefinitions::PersonModeValues.get(mode);
1343  } else {
1344  WRITE_ERRORF(TL("Invalid person mode '%' in edgeData definition '%'"), mode, id);
1345  return;
1346  }
1347  }
1348  if (edgesFile != "") {
1349  std::ifstream strm(edgesFile.c_str());
1350  if (!strm.good()) {
1351  throw ProcessError("Could not load names of edges for edgeData definition '" + id + "' from '" + edgesFile + "'.");
1352  }
1353  while (strm.good()) {
1354  std::string name;
1355  strm >> name;
1356  // maybe we're loading an edge-selection
1357  if (StringUtils::startsWith(name, "edge:")) {
1358  edgeIDs.push_back(name.substr(5));
1359  } else if (name != "") {
1360  edgeIDs.push_back(name);
1361  }
1362  }
1363  }
1364  std::vector<MSEdge*> edges;
1365  for (const std::string& edgeID : edgeIDs) {
1366  MSEdge* edge = MSEdge::dictionary(edgeID);
1367  if (edge == nullptr) {
1368  WRITE_ERRORF(TL("Unknown edge '%' in edgeData definition '%'"), edgeID, id);
1369  return;
1370  }
1371  edges.push_back(edge);
1372  }
1373  bool useLanes = objecttype == SUMO_TAG_MEANDATA_LANE;
1374  if (useLanes && MSGlobals::gUseMesoSim && !OptionsCont::getOptions().getBool("meso-lane-queue")) {
1375  WRITE_WARNINGF(TL("LaneData '%' requested for mesoscopic simulation but --meso-lane-queue is not active. Falling back to edgeData."), id);
1376  useLanes = false;
1377  }
1378  try {
1379  myDetectorBuilder.createEdgeLaneMeanData(id, period, begin, end,
1380  type, useLanes,
1381  // equivalent to TplConvert::_2bool used in SUMOSAXAttributes::getBool
1382  excludeEmpty[0] != 't' && excludeEmpty[0] != 'T' && excludeEmpty[0] != '1' && excludeEmpty[0] != 'x',
1383  excludeEmpty == "defaults", withInternal, trackVehicles, detectPersons,
1384  maxTravelTime, minSamples, haltingSpeedThreshold, vtypes, writeAttributes, edges, aggregate,
1386  } catch (InvalidArgument& e) {
1387  WRITE_ERROR(e.what());
1388  } catch (IOError& e) {
1389  WRITE_ERROR(e.what());
1390  }
1391 }
1392 
1393 
1394 void
1396  bool ok = true;
1397  const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
1398  const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
1399  if (!MSGlobals::gUsingInternalLanes && (fromID[0] == ':' || toID[0] == ':')) {
1400  std::string tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, nullptr, ok, "");
1401  if (tlID != "") {
1402  int tlLinkIdx = attrs.get<int>(SUMO_ATTR_TLLINKINDEX, nullptr, ok);
1404  }
1405  return;
1406  }
1407 
1408  myCurrentLink = nullptr;
1409  try {
1410  const int fromLaneIdx = attrs.get<int>(SUMO_ATTR_FROM_LANE, nullptr, ok);
1411  const int toLaneIdx = attrs.get<int>(SUMO_ATTR_TO_LANE, nullptr, ok);
1412  LinkDirection dir = parseLinkDir(attrs.get<std::string>(SUMO_ATTR_DIR, nullptr, ok));
1413  LinkState state = parseLinkState(attrs.get<std::string>(SUMO_ATTR_STATE, nullptr, ok));
1414  const double foeVisibilityDistance = attrs.getOpt<double>(SUMO_ATTR_VISIBILITY_DISTANCE, nullptr, ok, state == LINKSTATE_ZIPPER ? 100 : 4.5);
1415  const bool keepClear = attrs.getOpt<bool>(SUMO_ATTR_KEEP_CLEAR, nullptr, ok, true);
1416  const bool indirect = attrs.getOpt<bool>(SUMO_ATTR_INDIRECT, nullptr, ok, false);
1417  std::string tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, nullptr, ok, "");
1418  std::string viaID = attrs.getOpt<std::string>(SUMO_ATTR_VIA, nullptr, ok, "");
1419 
1421  if (from == nullptr) {
1422  WRITE_ERRORF(TL("Unknown from-edge '%' in connection."), fromID);
1423  return;
1424  }
1425  myPreviousEdgeIdx = from->getNumericalID();
1426  MSEdge* to = MSEdge::dictionary(toID);
1427  if (to == nullptr) {
1428  WRITE_ERRORF(TL("Unknown to-edge '%' in connection."), toID);
1429  return;
1430  }
1431  if (fromLaneIdx < 0 || fromLaneIdx >= (int)from->getLanes().size() ||
1432  toLaneIdx < 0 || toLaneIdx >= (int)to->getLanes().size()) {
1433  WRITE_ERRORF(TL("Invalid lane index in connection from '%' to '%'."), from->getID(), to->getID());
1434  return;
1435  }
1436  MSLane* fromLane = from->getLanes()[fromLaneIdx];
1437  MSLane* toLane = to->getLanes()[toLaneIdx];
1438  assert(fromLane);
1439  assert(toLane);
1440 
1441  MSTrafficLightLogic* logic = nullptr;
1442  int tlLinkIdx = -1;
1443  if (tlID != "") {
1444  tlLinkIdx = attrs.get<int>(SUMO_ATTR_TLLINKINDEX, nullptr, ok);
1445  // make sure that the index is in range
1447  if ((tlLinkIdx < 0 || tlLinkIdx >= (int)logic->getCurrentPhaseDef().getState().size())
1448  && logic->getLogicType() != TrafficLightType::RAIL_SIGNAL
1449  && logic->getLogicType() != TrafficLightType::RAIL_CROSSING) {
1450  WRITE_ERROR("Invalid " + toString(SUMO_ATTR_TLLINKINDEX) + " '" + toString(tlLinkIdx) +
1451  "' in connection controlled by '" + tlID + "'");
1452  return;
1453  }
1454  if (!ok) {
1455  return;
1456  }
1457  }
1458  double length;
1459  // build the link
1460  MSLane* via = nullptr;
1461  if (viaID != "" && MSGlobals::gUsingInternalLanes) {
1462  via = MSLane::dictionary(viaID);
1463  if (via == nullptr) {
1464  WRITE_ERROR("An unknown lane ('" + viaID +
1465  "') should be set as a via-lane for lane '" + toLane->getID() + "'.");
1466  return;
1467  }
1468  length = via->getLength();
1469  } else if (toLane->getEdge().isCrossing()) {
1470  length = toLane->getLength();
1471  } else {
1472  length = fromLane->getShape()[-1].distanceTo(toLane->getShape()[0]);
1473  }
1474  myCurrentLink = new MSLink(fromLane, toLane, via, dir, state, length, foeVisibilityDistance, keepClear, logic, tlLinkIdx, indirect);
1475  if (via != nullptr) {
1476  via->addIncomingLane(fromLane, myCurrentLink);
1477  } else {
1478  toLane->addIncomingLane(fromLane, myCurrentLink);
1479  }
1480  toLane->addApproachingLane(fromLane, myNetworkVersion < MMVersion(0, 25));
1481 
1482  // if a traffic light is responsible for it, inform the traffic light
1483  // check whether this link is controlled by a traffic light
1484  // we can not reuse logic here because it might be an inactive one
1485  if (tlID != "") {
1486  myJunctionControlBuilder.getTLLogic(tlID).addLink(myCurrentLink, fromLane, tlLinkIdx);
1487  }
1488  // add the link
1489  fromLane->addLink(myCurrentLink);
1490 
1491  } catch (InvalidArgument& e) {
1492  WRITE_ERROR(e.what());
1493  }
1494 }
1495 
1496 
1497 void
1499  if (myCurrentLink == nullptr) {
1500  throw InvalidArgument(toString(SUMO_TAG_CONFLICT) + " must occur within a " + toString(SUMO_TAG_CONNECTION) + " element");
1501  }
1503  return;
1504  }
1505  bool ok = true;
1506  const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
1507  const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
1508  const int fromLaneIdx = attrs.get<int>(SUMO_ATTR_FROM_LANE, nullptr, ok);
1509  const int toLaneIdx = attrs.get<int>(SUMO_ATTR_TO_LANE, nullptr, ok);
1510  double startPos = attrs.get<double>(SUMO_ATTR_STARTPOS, nullptr, ok);
1511  double endPos = attrs.get<double>(SUMO_ATTR_ENDPOS, nullptr, ok);
1512  MSEdge* from = MSEdge::dictionary(fromID);
1513  if (from == nullptr) {
1514  WRITE_ERRORF(TL("Unknown from-edge '%' in conflict."), fromID);
1515  return;
1516  }
1517  MSEdge* to = MSEdge::dictionary(toID);
1518  if (to == nullptr) {
1519  WRITE_ERRORF(TL("Unknown to-edge '%' in conflict."), toID);
1520  return;
1521  }
1522  if (fromLaneIdx < 0 || fromLaneIdx >= (int)from->getLanes().size() ||
1523  toLaneIdx < 0 || toLaneIdx >= (int)to->getLanes().size()) {
1524  WRITE_ERRORF(TL("Invalid lane index in conflict with '%' to '%'."), from->getID(), to->getID());
1525  return;
1526  }
1527  MSLane* fromLane = from->getLanes()[fromLaneIdx];
1528  MSLane* toLane = to->getLanes()[toLaneIdx];
1529  assert(fromLane);
1530  assert(toLane);
1531  myCurrentLink->addCustomConflict(fromLane, toLane, startPos, endPos);
1532 }
1533 
1534 
1536 NLHandler::parseLinkDir(const std::string& dir) {
1537  if (SUMOXMLDefinitions::LinkDirections.hasString(dir)) {
1539  } else {
1540  throw InvalidArgument("Unrecognised link direction '" + dir + "'.");
1541  }
1542 }
1543 
1544 
1545 LinkState
1546 NLHandler::parseLinkState(const std::string& state) {
1547  if (SUMOXMLDefinitions::LinkStates.hasString(state)) {
1548  return SUMOXMLDefinitions::LinkStates.get(state);
1549  } else {
1550  if (state == "t") { // legacy networks
1551  // WRITE_WARNING(TL("Obsolete link state 't'. Use 'o' instead"));
1553  } else {
1554  throw InvalidArgument("Unrecognised link state '" + state + "'.");
1555  }
1556  }
1557 }
1558 
1559 
1560 // ----------------------------------
1561 void
1563  if (myNetIsLoaded) {
1564  //WRITE_WARNING(TL("POIs and Polygons should be loaded using option --po-files"))
1565  return;
1566  }
1567  bool ok = true;
1568  PositionVector s = attrs.get<PositionVector>(SUMO_ATTR_NET_OFFSET, nullptr, ok);
1569  Boundary convBoundary = attrs.get<Boundary>(SUMO_ATTR_CONV_BOUNDARY, nullptr, ok);
1570  Boundary origBoundary = attrs.get<Boundary>(SUMO_ATTR_ORIG_BOUNDARY, nullptr, ok);
1571  std::string proj = attrs.get<std::string>(SUMO_ATTR_ORIG_PROJ, nullptr, ok);
1572  if (ok) {
1573  Position networkOffset = s[0];
1574  GeoConvHelper::init(proj, networkOffset, origBoundary, convBoundary);
1575  if (OptionsCont::getOptions().getBool("fcd-output.geo") && !GeoConvHelper::getFinal().usingGeoProjection()) {
1576  WRITE_WARNING(TL("no valid geo projection loaded from network. fcd-output.geo will not work"));
1577  }
1578  }
1579 }
1580 
1581 
1582 void
1584  bool ok = true;
1585  myCurrentIsBroken = false;
1586  // get the id, report an error if not given or empty...
1587  myCurrentDistrictID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1588  if (!ok) {
1589  myCurrentIsBroken = true;
1590  return;
1591  }
1592  try {
1593  const std::string sinkID = myCurrentDistrictID + "-sink";
1594  const std::string sourceID = myCurrentDistrictID + "-source";
1595 
1596  MSEdge* sink = myEdgeControlBuilder.buildEdge(sinkID, SumoXMLEdgeFunc::CONNECTOR, "", "", -1, 0);
1597  if (!MSEdge::dictionary(sinkID, sink)) {
1598  delete sink;
1599  if (OptionsCont::getOptions().getBool("junction-taz")
1600  && myNet.getJunctionControl().get(myCurrentDistrictID) != nullptr) {
1601  // overwrite junction taz
1602  sink = MSEdge::dictionary(sinkID);
1604  WRITE_WARNINGF(TL("Replacing junction-taz '%' with loaded TAZ."), myCurrentDistrictID);
1605  } else {
1606  throw InvalidArgument("Another edge with the id '" + sinkID + "' exists.");
1607  }
1608  } else {
1609  sink->initialize(new std::vector<MSLane*>());
1610  }
1611  MSEdge* source = myEdgeControlBuilder.buildEdge(sourceID, SumoXMLEdgeFunc::CONNECTOR, "", "", -1, 0);
1612  if (!MSEdge::dictionary(sourceID, source)) {
1613  delete source;
1614  if (OptionsCont::getOptions().getBool("junction-taz")
1615  && myNet.getJunctionControl().get(myCurrentDistrictID) != nullptr) {
1616  // overwrite junction taz
1617  source = MSEdge::dictionary(sourceID);
1619  } else {
1620  throw InvalidArgument("Another edge with the id '" + sourceID + "' exists.");
1621  }
1622  } else {
1623  source->initialize(new std::vector<MSLane*>());
1624  }
1625  sink->setOtherTazConnector(source);
1626  source->setOtherTazConnector(sink);
1627  const std::vector<std::string>& desc = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_EDGES, myCurrentDistrictID.c_str(), ok);
1628  for (const std::string& eID : desc) {
1629  MSEdge* edge = MSEdge::dictionary(eID);
1630  // check whether the edge exists
1631  if (edge == nullptr) {
1632  throw InvalidArgument("The edge '" + eID + "' within district '" + myCurrentDistrictID + "' is not known.");
1633  }
1634  source->addSuccessor(edge);
1635  edge->addSuccessor(sink);
1636  }
1637  source->setParameter("taz", myCurrentDistrictID);
1638  sink->setParameter("taz", myCurrentDistrictID);
1639  RGBColor color = attrs.getOpt<RGBColor>(SUMO_ATTR_COLOR, myCurrentDistrictID.c_str(), ok, RGBColor::parseColor("1.0,.33,.33"));
1640  const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, myCurrentDistrictID.c_str(), ok, "");
1641  source->setParameter("tazColor", toString(color));
1642  sink->setParameter("tazColor", toString(color));
1643 
1644  if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
1646  const bool fill = attrs.getOpt<bool>(SUMO_ATTR_FILL, myCurrentDistrictID.c_str(), ok, false);
1647  if (shape.size() != 0) {
1648  if (!myNet.getShapeContainer().addPolygon(myCurrentDistrictID, "taz", color, 0, 0, "", false, shape, false, fill, 1.0, false, name)) {
1649  WRITE_WARNINGF(TL("Skipping visualization of taz '%', polygon already exists."), myCurrentDistrictID);
1650  } else {
1652  myCurrentIsBroken = false;
1653  }
1654  }
1655  }
1656  } catch (InvalidArgument& e) {
1657  WRITE_ERROR(e.what());
1658  myCurrentIsBroken = true;
1659  }
1660 }
1661 
1662 
1663 void
1664 NLHandler::addDistrictEdge(const SUMOSAXAttributes& attrs, bool isSource) {
1665  if (myCurrentIsBroken) {
1666  // earlier error
1667  return;
1668  }
1669  bool ok = true;
1670  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, myCurrentDistrictID.c_str(), ok);
1671  MSEdge* succ = MSEdge::dictionary(id);
1672  if (succ != nullptr) {
1673  // connect edge
1674  if (isSource) {
1675  MSEdge::dictionary(myCurrentDistrictID + "-source")->addSuccessor(succ);
1676  } else {
1677  succ->addSuccessor(MSEdge::dictionary(myCurrentDistrictID + "-sink"));
1678  }
1679  } else {
1680  WRITE_ERRORF(TL("At district '%': succeeding edge '%' does not exist."), myCurrentDistrictID, id);
1681  }
1682 }
1683 
1684 
1685 void
1687  bool ok = true;
1688  const std::vector<std::string>& edgeIDs = attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, nullptr, ok);
1689  if (ok) {
1690  for (const std::string& eID : edgeIDs) {
1691  MSEdge* edge = MSEdge::dictionary(eID);
1692  if (edge == nullptr) {
1693  WRITE_ERRORF(TL("Unknown edge '%' in roundabout"), eID);
1694  } else {
1695  edge->markAsRoundabout();
1696  }
1697  }
1698  }
1699 }
1700 
1701 
1702 void
1704  bool ok = true;
1705  MESegment::MesoEdgeType edgeType = myNet.getMesoType(""); // init defaults
1706  edgeType.tauff = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MESO_TAUFF, myCurrentTypeID.c_str(), ok, edgeType.tauff);
1707  edgeType.taufj = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MESO_TAUFJ, myCurrentTypeID.c_str(), ok, edgeType.taufj);
1708  edgeType.taujf = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MESO_TAUJF, myCurrentTypeID.c_str(), ok, edgeType.taujf);
1709  edgeType.taujj = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MESO_TAUJJ, myCurrentTypeID.c_str(), ok, edgeType.taujj);
1710  edgeType.jamThreshold = attrs.getOpt<double>(SUMO_ATTR_JAM_DIST_THRESHOLD, myCurrentTypeID.c_str(), ok, edgeType.jamThreshold);
1711  edgeType.junctionControl = attrs.getOpt<bool>(SUMO_ATTR_MESO_JUNCTION_CONTROL, myCurrentTypeID.c_str(), ok, edgeType.junctionControl);
1712  edgeType.tlsPenalty = attrs.getOpt<double>(SUMO_ATTR_MESO_TLS_PENALTY, myCurrentTypeID.c_str(), ok, edgeType.tlsPenalty);
1713  edgeType.tlsFlowPenalty = attrs.getOpt<double>(SUMO_ATTR_MESO_TLS_FLOW_PENALTY, myCurrentTypeID.c_str(), ok, edgeType.tlsFlowPenalty);
1715  edgeType.overtaking = attrs.getOpt<bool>(SUMO_ATTR_MESO_OVERTAKING, myCurrentTypeID.c_str(), ok, edgeType.overtaking);
1716 
1717  if (ok) {
1718  myNet.addMesoType(myCurrentTypeID, edgeType);
1719  }
1720  if (myNetIsLoaded) {
1721  myHaveSeenMesoEdgeType = true;
1722  }
1723 }
1724 
1725 // ----------------------------------
1726 void
1728  try {
1730  } catch (InvalidArgument& e) {
1731  WRITE_ERROR(e.what());
1732  }
1733 }
1734 
1735 
1736 void
1738  if (!myCurrentIsBroken) {
1739  try {
1741  } catch (InvalidArgument& e) {
1742  WRITE_ERROR(e.what());
1743  myCurrentIsBroken = true;
1744  }
1745  }
1746  myCurrentWAUTID = "";
1747 }
1748 
1749 
1750 Position
1751 NLShapeHandler::getLanePos(const std::string& poiID, const std::string& laneID, double lanePos, bool friendlyPos, double lanePosLat) {
1752  MSLane* lane = MSLane::dictionary(laneID);
1753  if (lane == nullptr) {
1754  WRITE_ERRORF(TL("Lane '%' to place poi '%' on is not known."), laneID, poiID);
1755  return Position::INVALID;
1756  }
1757  if (lanePos < 0) {
1758  lanePos = lane->getLength() + lanePos;
1759  }
1760  if ((lanePos < 0) && friendlyPos) {
1761  lanePos = 0;
1762  }
1763  if ((lanePos > lane->getLength()) && friendlyPos) {
1764  lanePos = lane->getLength();
1765  }
1766  if (lanePos < 0 || lanePos > lane->getLength()) {
1767  WRITE_WARNINGF(TL("lane position % for poi '%' is not valid."), toString(lanePos), poiID);
1768  }
1769  return lane->geometryPositionAtOffset(lanePos, -lanePosLat);
1770 }
1771 
1772 
1775  if (rs == nullptr) {
1776  throw InvalidArgument("Rail signal '" + toString((SumoXMLTag)element) + "' constraint must occur within a railSignalConstraints element");
1777  }
1778  bool ok = true;
1779  const std::string tripId = attrs.get<std::string>(SUMO_ATTR_TRIP_ID, nullptr, ok);
1780  const std::string signalID = attrs.get<std::string>(SUMO_ATTR_TLID, nullptr, ok);
1781  const std::string foesString = attrs.get<std::string>(SUMO_ATTR_FOES, nullptr, ok);
1782  const std::vector<std::string> foes = StringTokenizer(foesString).getVector();
1783  const int limit = attrs.getOpt<int>(SUMO_ATTR_LIMIT, nullptr, ok, (int)foes.size());
1784  const bool active = attrs.getOpt<bool>(SUMO_ATTR_ACTIVE, nullptr, ok, true);
1785 
1786  if (!MSNet::getInstance()->getTLSControl().knows(signalID)) {
1787  throw InvalidArgument("Rail signal '" + signalID + "' in railSignalConstraints is not known");
1788  }
1789  MSRailSignal* signal = dynamic_cast<MSRailSignal*>(MSNet::getInstance()->getTLSControl().get(signalID).getDefault());
1790  if (signal == nullptr) {
1791  throw InvalidArgument("Traffic light '" + signalID + "' is not a rail signal");
1792  }
1794  switch (element) {
1795  case SUMO_TAG_PREDECESSOR:
1796  type = MSRailSignalConstraint::ConstraintType::PREDECESSOR;
1797  break;
1799  type = MSRailSignalConstraint::ConstraintType::INSERTION_PREDECESSOR;
1800  break;
1802  type = MSRailSignalConstraint::ConstraintType::FOE_INSERTION;
1803  break;
1805  type = MSRailSignalConstraint::ConstraintType::INSERTION_ORDER;
1806  break;
1808  type = MSRailSignalConstraint::ConstraintType::BIDI_PREDECESSOR;
1809  break;
1810  default:
1811  throw InvalidArgument("Unsupported rail signal constraint '" + toString((SumoXMLTag)element) + "'");
1812  }
1813  Parameterised* result = nullptr;
1814  if (ok) {
1815  for (const std::string& foe : foes) {
1816  MSRailSignalConstraint* c = new MSRailSignalConstraint_Predecessor(type, signal, foe, limit, active);
1817  rs->addConstraint(tripId, c);
1818  // XXX if there are multiple foes, only one constraint will receive the parameters
1819  result = c;
1820  }
1821  }
1822  return result;
1823 }
1824 
1825 
1826 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:296
#define WRITE_ERRORF(...)
Definition: MsgHandler.h:305
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:304
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:295
#define TL(string)
Definition: MsgHandler.h:315
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:46
#define SUMOTime_MAX_PERIOD
Definition: SUMOTime.h:36
#define TIME2STEPS(x)
Definition: SUMOTime.h:57
SUMOVehicleClass getVehicleClassID(const std::string &name)
Returns the class id of the abstract class given by its name.
const SVCPermissions SVCAll
all VClasses are allowed
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
TrafficLightType
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_TRACTION_SUBSTATION
A traction substation.
@ SUMO_TAG_PHASE
a single phase description
@ SUMO_TAG_RAILSIGNAL_CONSTRAINTS
Constraints on switching a rail signal.
@ SUMO_TAG_BIDI_PREDECESSOR
Predecessor constraint for rail signal before bidirectional section.
@ SUMO_TAG_NET
root element of a network file
@ SUMO_TAG_REROUTER
A rerouter.
@ SUMO_TAG_INSERTION_PREDECESSOR
Predecessor constraint on insertion before rail signal.
@ SUMO_TAG_STOPOFFSET
Information on vClass specific stop offsets at lane end.
@ SUMO_TAG_WAUT_JUNCTION
@ SUMO_TAG_REQUEST
description of a logic request within the junction
@ SUMO_TAG_WAUT_SWITCH
@ SUMO_TAG_ROUTEPROBE
a routeprobe detector
@ SUMO_TAG_TAZ
a traffic assignment zone
@ SUMO_TAG_TIMEDEVENT
The definition of a periodic event.
@ SUMO_TAG_E2DETECTOR
an e2 detector
@ SUMO_TAG_CHARGING_STATION
A Charging Station.
@ SUMO_TAG_CONFLICT
conflict between two connections
@ SUMO_TAG_ACCESS
An access point for a train stop.
@ SUMO_TAG_CONDITION
a condition for phase switching
@ SUMO_TAG_CONTAINER_STOP
A container stop.
@ SUMO_TAG_TAZSINK
a sink within a district (connection road)
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_MESO
edge-specific meso settings
@ SUMO_TAG_FUNCTION
a sequence of assignments evaluated in the context of passed arguments
@ SUMO_TAG_MEANDATA_LANE
a lane based mean data detector
@ SUMO_TAG_LOCATION
@ SUMO_TAG_RESTRICTION
begin/end of the description of an edge restriction
@ SUMO_TAG_OVERHEAD_WIRE_CLAMP
An overhead wire clamp (connection of wires in opposite directions)
@ SUMO_TAG_CONNECTION
connectioon between two lanes
@ SUMO_TAG_PARKING_AREA
A parking area.
@ SUMO_TAG_ROUNDABOUT
roundabout defined in junction
@ SUMO_TAG_DET_ENTRY
an e3 entry point
@ SUMO_TAG_TLLOGIC
a traffic light logic
@ SUMO_TAG_PARKING_SPACE
A parking space for a single vehicle within a parking area.
@ SUMO_TAG_FOE_INSERTION
Predecessor constraint on switching a rail signal.
@ SUMO_TAG_JUNCTION
begin/end of the description of a junction
@ SUMO_TAG_MEANDATA_EDGE
an edge based mean data detector
@ SUMO_TAG_OVERHEAD_WIRE_SECTION
An overhead wire section.
@ SUMO_TAG_VTYPEPROBE
a vtypeprobe detector
@ SUMO_TAG_TRAIN_STOP
A train stop (alias for bus stop)
@ SUMO_TAG_OVERHEAD_WIRE_SEGMENT
An overhead wire segment.
@ SUMO_TAG_LANE
begin/end of the description of a single lane
@ SUMO_TAG_INSTANT_INDUCTION_LOOP
An instantenous induction loop.
@ SUMO_TAG_PARAM
parameter associated to a certain key
@ SUMO_TAG_E1DETECTOR
an e1 detector
@ SUMO_TAG_INSERTION_ORDER
Predecessor constraint on insertion before rail signal.
@ SUMO_TAG_DET_EXIT
an e3 exit point
@ SUMO_TAG_TYPE
type (edge)
@ SUMO_TAG_VAPORIZER
vaporizer of vehicles
@ SUMO_TAG_LANE_AREA_DETECTOR
alternative tag for e2 detector
@ SUMO_TAG_WAUT
@ SUMO_TAG_ASSIGNMENT
a conditional variable assignment for phase switching
@ SUMO_TAG_TAZSOURCE
a source within a district (connection road)
@ SUMO_TAG_NEIGH
begin/end of the description of a neighboring lane
@ SUMO_TAG_INDUCTION_LOOP
alternative tag for e1 detector
@ SUMO_TAG_CALIBRATOR
A calibrator placed over edge.
@ SUMO_TAG_ENTRY_EXIT_DETECTOR
alternative tag for e3 detector
@ SUMO_TAG_E3DETECTOR
an e3 detector
@ SUMO_TAG_VSS
A variable speed sign.
@ SUMO_TAG_PREDECESSOR
Predecessor constraint on switching a rail signal.
@ SUMO_TAG_EDGE
begin/end of the description of an edge
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)....
SumoXMLEdgeFunc
Numbers representing special SUMO-XML-attribute values for representing edge functions used in netbui...
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic,...
@ LINKSTATE_ZIPPER
This is an uncontrolled, zipper-merge link.
@ LINKSTATE_TL_OFF_BLINKING
The link is controlled by a tls which is off and blinks, has to brake.
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
@ SUMO_ATTR_EXPECT_ARRIVAL
@ SUMO_ATTR_STARTPOS
@ SUMO_ATTR_DISALLOW
@ SUMO_ATTR_CONV_BOUNDARY
@ SUMO_ATTR_ALLOW
@ SUMO_ATTR_LANE
@ SUMO_ATTR_NET_OFFSET
@ SUMO_ATTR_NARGS
The number of arguments for a condition function.
@ SUMO_ATTR_CONT
@ SUMO_ATTR_ORIG_BOUNDARY
@ SUMO_ATTR_MESO_TLS_FLOW_PENALTY
@ SUMO_ATTR_LATEST_END
The maximum time within the cycle for switching (for coordinated actuation)
@ SUMO_ATTR_MESO_JUNCTION_CONTROL
@ SUMO_ATTR_RED
red duration of a phase
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_VALUE
@ SUMO_ATTR_VIA
@ SUMO_ATTR_NEXT_EDGES
@ SUMO_ATTR_FILE
@ SUMO_ATTR_PROCEDURE
@ SUMO_ATTR_INDIRECT
Whether this connection is an indirect (left) turn.
@ SUMO_ATTR_Y
@ SUMO_ATTR_FROM_LANE
@ SUMO_ATTR_Z
@ SUMO_ATTR_EDGE
@ SUMO_ATTR_JAM_DIST_THRESHOLD
@ SUMO_ATTR_MESO_OVERTAKING
@ SUMO_ATTR_TRACK_VEHICLES
@ SUMO_ATTR_RESPONSE
@ SUMO_ATTR_ENDPOS
@ SUMO_ATTR_TARGETLANE
@ SUMO_ATTR_OFFSET
@ SUMO_ATTR_X
@ SUMO_ATTR_WAUT_ID
@ SUMO_ATTR_YELLOW
yellow duration of a phase
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_INTLANES
@ SUMO_ATTR_VEHICLEEXTENSION
vehicle extension time of a phase
@ SUMO_ATTR_WITH_INTERNAL
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_START_PROG
@ SUMO_ATTR_BIDI
@ SUMO_ATTR_AGGREGATE
@ SUMO_ATTR_HALTING_TIME_THRESHOLD
@ SUMO_ATTR_LIMIT
@ SUMO_ATTR_PRIORITY
@ SUMO_ATTR_MESO_TAUFF
@ SUMO_ATTR_LANES
@ SUMO_ATTR_VTYPES
@ SUMO_ATTR_SHAPE
edge: the shape in xml-definition
@ SUMO_ATTR_LEFTHAND
@ SUMO_ATTR_NEXT
succesor phase index
@ SUMO_ATTR_MAX_TRAVELTIME
@ SUMO_ATTR_MESO_MINOR_PENALTY
@ SUMO_ATTR_INCLANES
@ SUMO_ATTR_CHANGE_LEFT
@ SUMO_ATTR_INDEX
@ SUMO_ATTR_FILL
Fill the polygon.
@ SUMO_ATTR_NAME
@ SUMO_ATTR_ORIG_PROJ
@ SUMO_ATTR_PERIOD
@ SUMO_ATTR_FINAL_TARGET
The condition expression for switching into this phase when the active phase must end.
@ SUMO_ATTR_HALTING_SPEED_THRESHOLD
@ SUMO_ATTR_HIGHER_SPEED
@ SUMO_ATTR_TRIP_ID
@ SUMO_ATTR_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_ACCELERATION
@ SUMO_ATTR_CHANGE_RIGHT
@ SUMO_ATTR_TLID
link,node: the traffic light id responsible for this link
@ SUMO_ATTR_VCLASS
@ SUMO_ATTR_DISTANCE
@ SUMO_ATTR_EARLY_TARGET
The condition expression for an early switch into this phase.
@ SUMO_ATTR_MESO_TAUJF
@ SUMO_ATTR_SHOW_DETECTOR
@ SUMO_ATTR_FOES
@ SUMO_ATTR_FRIENDLY_POS
@ SUMO_ATTR_TO_LANE
@ SUMO_ATTR_MIN_SAMPLES
@ SUMO_ATTR_JUNCTION_ID
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_LENGTH
@ SUMO_ATTR_VERSION
@ SUMO_ATTR_COLOR
A color information.
@ SUMO_ATTR_ID
@ SUMO_ATTR_MAXDURATION
maximum duration of a phase
@ SUMO_ATTR_PROGRAMID
@ SUMO_ATTR_OUTLINESHAPE
edge: the outline shape in xml-definition
@ SUMO_ATTR_FUNCTION
@ SUMO_ATTR_MESO_TAUFJ
@ SUMO_ATTR_VISIBILITY_DISTANCE
foe visibility distance of a link
@ SUMO_ATTR_OPEN_ENTRY
@ SUMO_ATTR_MESO_TAUJJ
@ SUMO_ATTR_DURATION
@ SUMO_ATTR_WIDTH
@ SUMO_ATTR_CROSSING_EDGES
the edges crossed by a pedestrian crossing
@ SUMO_ATTR_SYNCHRON
@ SUMO_ATTR_DIR
The abstract direction of a link.
@ SUMO_ATTR_TLLINKINDEX
link: the index of the link within the traffic light
@ SUMO_ATTR_MINDURATION
@ SUMO_ATTR_CHECK
The expression for a condition assignment.
@ SUMO_ATTR_MESO_TLS_PENALTY
@ SUMO_ATTR_KEY
@ SUMO_ATTR_REF_TIME
@ SUMO_ATTR_KEEP_CLEAR
Whether vehicles must keep the junction clear.
@ SUMO_ATTR_POSITION
@ SUMO_ATTR_STATE
The state of a link.
@ SUMO_ATTR_FRICTION
@ SUMO_ATTR_TIME
trigger: the time of the step
@ SUMO_ATTR_WRITE_ATTRIBUTES
@ SUMO_ATTR_ACTIVE
@ SUMO_ATTR_DETECT_PERSONS
@ SUMO_ATTR_EXCLUDE_EMPTY
@ SUMO_ATTR_EDGESFILE
@ SUMO_ATTR_EARLIEST_END
The minimum time within the cycle for switching (for coordinated actuation)
const double SUMO_const_laneWidth
Definition: StdDefs.h:48
std::pair< int, double > MMVersion
(M)ajor/(M)inor version for written networks and default version for loading
Definition: StdDefs.h:67
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:39
static std::string checkForRelativity(const std::string &filename, const std::string &basePath)
Returns the path from a configuration so that it is accessable from the current working directory.
const std::string & getFileName() const
returns the current file name
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
static bool init(OptionsCont &oc)
Initialises the processing and the final instance using the given options.
A road/street connecting two junctions.
Definition: MSEdge.h:77
bool isCrossing() const
return whether this edge is a pedestrian crossing
Definition: MSEdge.h:273
void setOtherTazConnector(const MSEdge *edge)
Definition: MSEdge.h:295
void setJunctions(MSJunction *from, MSJunction *to)
Definition: MSEdge.cpp:1267
void addSuccessor(MSEdge *edge, const MSEdge *via=nullptr)
Adds an edge to the list of edges which may be reached from this edge and to the incoming of the othe...
Definition: MSEdge.cpp:1191
static MSEdge * dictionaryHint(const std::string &id, const int startIdx)
Returns the MSEdge associated to the key id giving a hint with a numerical id.
Definition: MSEdge.cpp:1021
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:168
void initialize(const std::vector< MSLane * > *lanes)
Initialize the edge.
Definition: MSEdge.cpp:102
void resetTAZ(MSJunction *junction)
Definition: MSEdge.cpp:182
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn't already in the dictionary....
Definition: MSEdge.cpp:995
void markAsRoundabout()
Definition: MSEdge.h:710
static bool gUseMesoSim
Definition: MSGlobals.h:103
static bool gLefthand
Whether lefthand-drive is being simulated.
Definition: MSGlobals.h:171
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:78
The base class for an intersection.
Definition: MSJunction.h:58
void addOutgoing(MSEdge *edge)
Definition: MSJunction.h:128
void addIncoming(MSEdge *edge)
Definition: MSJunction.h:124
Representation of a lane in the micro simulation.
Definition: MSLane.h:84
void addApproachingLane(MSLane *lane, bool warnMultiCon)
Definition: MSLane.cpp:2770
void addIncomingLane(MSLane *lane, MSLink *viaLink)
Definition: MSLane.cpp:2760
void addLink(MSLink *link)
Delayed initialization.
Definition: MSLane.cpp:323
double getLength() const
Returns the lane's length.
Definition: MSLane.h:598
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:2395
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:756
const Position geometryPositionAtOffset(double offset, double lateralOffset=0) const
Definition: MSLane.h:552
virtual const PositionVector & getShape(bool) const
Definition: MSLane.h:294
The simulated network and simulation perfomer.
Definition: MSNet.h:89
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:184
MSTLLogicControl & getTLSControl()
Returns the tls logics control.
Definition: MSNet.h:451
ShapeContainer & getShapeContainer()
Returns the shapes container.
Definition: MSNet.h:501
void setPermissionsFound()
Labels the network to contain vehicle class permissions.
Definition: MSNet.h:213
MSJunctionControl & getJunctionControl()
Returns the junctions control.
Definition: MSNet.h:461
void addMesoType(const std::string &typeID, const MESegment::MesoEdgeType &edgeType)
Adds edge type specific meso parameters.
Definition: MSNet.cpp:362
void addRestriction(const std::string &id, const SUMOVehicleClass svc, const double speed)
Adds a restriction for an edge type.
Definition: MSNet.cpp:347
const MESegment::MesoEdgeType & getMesoType(const std::string &typeID)
Returns edge type specific meso parameters if no type specific parameters have been loaded,...
Definition: MSNet.cpp:367
The definition of a single phase of a tls logic.
std::string name
Optional name or description for the current phase.
std::vector< std::string > myTargetLaneSet
SUMOTime maxDuration
The maximum duration of the phase.
bool myCommit
the phase is a commit, compulsory directive for SOTL policies
static const SUMOTime UNSPECIFIED_DURATION
SUMOTime vehext
for NEMA phase
SUMOTime latestEnd
The maximum time within the cycle for switching (for coordinated actuation)
bool myTransientNotDecisional
the phase is a transient one or a decisional one, compulsory directive for SOTL policies
SUMOTime minDuration
The minimum duration of the phase.
SUMOTime yellow
for NEMA phase
SUMOTime red
for NEMA phase
SUMOTime myLastSwitch
Stores the timestep of the last on-switched of the phase.
SUMOTime duration
The duration of the phase.
std::vector< int > nextPhases
The index of the phase that suceeds this one (or -1)
std::string finalTarget
The condition expression for switching into this phase when the active phase must end.
std::string earlyTarget
The condition expression for an early switch into this phase.
SUMOTime earliestEnd
The minimum time within the cycle for switching (for coordinated actuation)
A base class for constraints.
A signal for rails.
Definition: MSRailSignal.h:46
void addConstraint(const std::string &tripId, MSRailSignalConstraint *constraint)
register constraint for signal switching
Parser and container for routes during their loading.
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs) override
Called on the opening of a tag;.
Storage for all programs of a single tls.
void addLink(MSLink *link, MSLane *lane, int pos)
MSTrafficLightLogic * getActive() const
MSTrafficLightLogic * getDefault() const
return the default program (that last used program except TRACI_PROGRAM)
void addWAUTJunction(const std::string &wautid, const std::string &tls, const std::string &proc, bool synchron)
Adds a tls to the list of tls to be switched by the named WAUT.
void addWAUT(SUMOTime refTime, const std::string &id, const std::string &startProg, SUMOTime period)
Adds a WAUT definition.
bool knows(const std::string &id) const
Returns the information whether the named tls is stored.
void addWAUTSwitch(const std::string &wautid, SUMOTime when, const std::string &to)
Adds a WAUT switch step to a previously built WAUT.
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
void closeWAUT(const std::string &wautid)
Closes loading of a WAUT.
The parent class for traffic light logics.
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:92
virtual void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:154
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
Definition: MsgHandler.cpp:79
Builds detectors for microsim.
void endE3Detector()
Builds of an e3 detector using collected values.
void createEdgeLaneMeanData(const std::string &id, SUMOTime frequency, SUMOTime begin, SUMOTime end, const std::string &type, const bool useLanes, const bool withEmpty, const bool printDefaults, const bool withInternal, const bool trackVehicles, const int detectPersons, const double maxTravelTime, const double minSamples, const double haltSpeed, const std::string &vTypes, const std::string &writeAttributes, std::vector< MSEdge * > edges, bool aggregate, const std::string &device)
Creates edge based mean data collector using the given specification.
MSLane * getLaneChecking(const std::string &laneID, SumoXMLTag type, const std::string &detid)
Returns the named lane.
void buildVTypeProbe(const std::string &id, const std::string &vtype, SUMOTime frequency, const std::string &device)
Builds a vTypeProbe and adds it to the net.
void addE3Exit(const std::string &lane, double pos, bool friendlyPos)
Builds an exit point of an e3 detector.
void buildRouteProbe(const std::string &id, const std::string &edge, SUMOTime frequency, SUMOTime begin, const std::string &device, const std::string &vTypes)
Builds a routeProbe and adds it to the net.
void addE3Entry(const std::string &lane, double pos, bool friendlyPos)
Builds an entry point of an e3 detector.
Parameterised * buildInductLoop(const std::string &id, const std::string &lane, double pos, double length, SUMOTime splInterval, const std::string &device, bool friendlyPos, const std::string name, const std::string &vTypes, const std::string &nextEdges, int detectPersons)
Builds an e1 detector and adds it to the net.
Parameterised * buildInstantInductLoop(const std::string &id, const std::string &lane, double pos, const std::string &device, bool friendlyPos, const std::string name, const std::string &vTypes, const std::string &nextEdges)
Builds an instantenous induction and adds it to the net.
Parameterised * buildE2Detector(const std::string &id, MSLane *lane, double pos, double endPos, double length, const std::string &device, SUMOTime frequency, SUMOTime haltingTimeThreshold, double haltingSpeedThreshold, double jamDistThreshold, const std::string name, const std::string &vTypes, const std::string &nextEdges, int detectPersons, bool friendlyPos, bool showDetector, MSTLLogicControl::TLSLogicVariants *tlls=0, MSLane *toLane=0)
Builds a new E2 detector and adds it to the net's detector control. Also performs some consistency ch...
Parameterised * beginE3Detector(const std::string &id, const std::string &device, SUMOTime splInterval, double haltingSpeedThreshold, SUMOTime haltingTimeThreshold, const std::string name, const std::string &vTypes, const std::string &nextEdges, int detectPersons, bool openEntry, bool expectArrival)
Stores temporary the initial information about an e3 detector to build.
std::string getCurrentE3ID() const
Returns the id of the currently built e3 detector.
void addAction(const SUMOSAXAttributes &attrs, const std::string &basePath)
Builds an action and saves it for further use.
Interface for building edges.
virtual MSEdge * closeEdge()
Closes the building of an edge; The edge is completely described by now and may not be opened again.
virtual void addNeigh(const std::string id)
Adds a neighbor to the current lane.
void closeLane()
Closes the building of a lane; The edge is completely described by now and may not be opened again.
std::string reportCurrentEdgeOrLane() const
Return info about currently processed edge or lane.
void beginEdgeParsing(const std::string &id, const SumoXMLEdgeFunc function, const std::string &streetName, const std::string &edgeType, int priority, const std::string &bidi, double distance)
Begins building of an MSEdge.
virtual void addCrossingEdges(const std::vector< std::string > &)
add the crossingEdges in a crossing edge if present
void addStopOffsets(const StopOffset &stopOffsets)
process a stopOffset element (originates either from the active edge or lane).
virtual MSLane * addLane(const std::string &id, double maxSpeed, double friction, double length, const PositionVector &shape, double width, SVCPermissions permissions, SVCPermissions changeLeft, SVCPermissions changeRight, int index, bool isRampAccel, const std::string &type, const PositionVector &outlineShape)
Adds a lane to the current edge.
virtual MSEdge * buildEdge(const std::string &id, const SumoXMLEdgeFunc function, const std::string &streetName, const std::string &edgeType, const int priority, const double distance)
Builds an edge instance (MSEdge in this case)
void addRequest(const SUMOSAXAttributes &attrs)
adds a request item to the current junction logic
Definition: NLHandler.cpp:724
bool myHaveSeenMesoEdgeType
whether edge type specific meso paramters were loaded
Definition: NLHandler.h:370
std::vector< Parameterised * > myLastParameterised
Definition: NLHandler.h:352
virtual void addE2Detector(const SUMOSAXAttributes &attrs)
Builds an e2 detector using the given specification.
Definition: NLHandler.cpp:1047
MSLink * myCurrentLink
the link element for the connection currently being parsed
Definition: NLHandler.h:382
void addRoundabout(const SUMOSAXAttributes &attrs)
Definition: NLHandler.cpp:1686
void addWAUTSwitch(const SUMOSAXAttributes &attrs)
Definition: NLHandler.cpp:684
virtual void addMesoEdgeType(const SUMOSAXAttributes &attrs)
Loads edge type specific meso parameters.
Definition: NLHandler.cpp:1703
bool myCurrentIsBroken
Definition: NLHandler.h:347
void addE3Entry(const SUMOSAXAttributes &attrs)
Adds an entry to the currently processed e3 detector.
Definition: NLHandler.cpp:1290
void beginEdgeParsing(const SUMOSAXAttributes &attrs)
begins the processing of an edge
Definition: NLHandler.cpp:417
bool myHaveSeenAdditionalSpeedRestrictions
whether additional files contained type-specific speed limits
Definition: NLHandler.h:367
std::string myCurrentDistrictID
The id of the current district.
Definition: NLHandler.h:330
void addPhase(const SUMOSAXAttributes &attrs)
adds a phase to the traffic lights logic currently build
Definition: NLHandler.cpp:804
MMVersion myNetworkVersion
the loaded network version
Definition: NLHandler.h:373
std::string myCurrentTypeID
The id of the currently processed edge type.
Definition: NLHandler.h:339
void addAssignment(const SUMOSAXAttributes &attrs)
adds a switching condition assignment to the traffic lights logic currently build
Definition: NLHandler.cpp:897
static Parameterised * addPredecessorConstraint(int element, const SUMOSAXAttributes &attrs, MSRailSignal *rs)
Definition: NLHandler.cpp:1774
virtual void addVTypeProbeDetector(const SUMOSAXAttributes &attrs)
Builds a vtype-detector using the given specification.
Definition: NLHandler.cpp:1002
void addDistrictEdge(const SUMOSAXAttributes &attrs, bool isSource)
Definition: NLHandler.cpp:1664
std::string myCurrentWAUTID
The id of the currently processed WAUT.
Definition: NLHandler.h:336
void parseLanes(const std::string &junctionID, const std::string &def, std::vector< MSLane * > &into, bool &ok)
Definition: NLHandler.cpp:619
void addFunction(const SUMOSAXAttributes &attrs)
adds a switching condition function to the traffic lights logic currently build
Definition: NLHandler.cpp:907
int myPreviousEdgeIdx
Definition: NLHandler.h:388
void addLane(const SUMOSAXAttributes &attrs)
adds a lane to the previously opened edge
Definition: NLHandler.cpp:511
void initJunctionLogic(const SUMOSAXAttributes &attrs)
begins the reading of a junction row logic
Definition: NLHandler.cpp:749
Parameterised myLastEdgeParameters
Definition: NLHandler.h:351
virtual void myEndElement(int element)
Called when a closing tag occurs.
Definition: NLHandler.cpp:307
bool myHaveSeenDefaultLength
whether the loaded network contains edges with default lengths
Definition: NLHandler.h:361
NLTriggerBuilder & myTriggerBuilder
The trigger builder to use.
Definition: NLHandler.h:321
virtual void addInstantE1Detector(const SUMOSAXAttributes &attrs)
Builds an e1 detector using the given specification.
Definition: NLHandler.cpp:969
virtual void openJunction(const SUMOSAXAttributes &attrs)
opens a junction for processing
Definition: NLHandler.cpp:574
virtual void endE3Detector()
Builds of an e3 detector using collected values.
Definition: NLHandler.cpp:1727
bool myAmParsingTLLogicOrJunction
internal information whether a tls-logic is currently read
Definition: NLHandler.h:333
JunctionGraph myJunctionGraph
Definition: NLHandler.h:386
void addDistrict(const SUMOSAXAttributes &attrs)
Definition: NLHandler.cpp:1583
bool myCurrentIsInternalToSkip
Information whether the currently parsed edge is internal and not wished, here.
Definition: NLHandler.h:314
NLEdgeControlBuilder & myEdgeControlBuilder
The edge builder to use.
Definition: NLHandler.h:324
void initTrafficLightLogic(const SUMOSAXAttributes &attrs)
begins the reading of a traffic lights logic
Definition: NLHandler.cpp:764
void closeWAUT()
Definition: NLHandler.cpp:1737
bool myHaveSeenInternalEdge
whether the loaded network contains internal lanes
Definition: NLHandler.h:355
NLHandler(const std::string &file, MSNet &net, NLDetectorBuilder &detBuilder, NLTriggerBuilder &triggerBuilder, NLEdgeControlBuilder &edgeBuilder, NLJunctionControlBuilder &junctionBuilder)
Constructor.
Definition: NLHandler.cpp:60
void addCondition(const SUMOSAXAttributes &attrs)
adds a switching condition to the traffic lights logic currently build
Definition: NLHandler.cpp:886
void setLocation(const SUMOSAXAttributes &attrs)
Parses network location description.
Definition: NLHandler.cpp:1562
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
Definition: NLHandler.cpp:87
bool myHaveSeenNeighs
whether the loaded network contains explicit neighbor lanes
Definition: NLHandler.h:364
virtual void openWAUT(const SUMOSAXAttributes &attrs)
Definition: NLHandler.cpp:656
LinkState parseLinkState(const std::string &state)
Parses the given character into an enumeration typed link state.
Definition: NLHandler.cpp:1546
NLDiscreteEventBuilder myActionBuilder
A builder for object actions.
Definition: NLHandler.h:311
NLDetectorBuilder & myDetectorBuilder
The detector builder to use.
Definition: NLHandler.h:318
void addConflict(const SUMOSAXAttributes &attrs)
Definition: NLHandler.cpp:1498
NLJunctionControlBuilder & myJunctionControlBuilder
The junction builder to use.
Definition: NLHandler.h:327
virtual void addE1Detector(const SUMOSAXAttributes &attrs)
Builds an e1 detector using the given specification.
Definition: NLHandler.cpp:920
virtual ~NLHandler()
Destructor.
Definition: NLHandler.cpp:83
void addE3Exit(const SUMOSAXAttributes &attrs)
Adds an exit to the currently processed e3 detector.
Definition: NLHandler.cpp:1303
void beginE3Detector(const SUMOSAXAttributes &attrs)
Starts building of an e3 detector using the given specification.
Definition: NLHandler.cpp:1246
virtual void closeEdge()
Closes the process of building an edge.
Definition: NLHandler.cpp:493
void closeFunction()
adds a switching condition function to the traffic lights logic currently build
Definition: NLHandler.cpp:915
bool myHaveJunctionHigherSpeeds
Whether the network was built with higher speed on junctions.
Definition: NLHandler.h:358
MSNet & myNet
The net to fill (preinitialised)
Definition: NLHandler.h:308
MSRailSignal * myConstrainedSignal
rail signal for which constraints are being loaded
Definition: NLHandler.h:379
LinkDirection parseLinkDir(const std::string &dir)
Parses the given character into an enumeration typed link direction.
Definition: NLHandler.cpp:1536
bool myNetIsLoaded
whether the location element was already loadee
Definition: NLHandler.h:376
void addWAUTJunction(const SUMOSAXAttributes &attrs)
Definition: NLHandler.cpp:703
virtual void addRouteProbeDetector(const SUMOSAXAttributes &attrs)
Builds a routeProbe-detector using the given specification.
Definition: NLHandler.cpp:1023
virtual void addEdgeLaneMeanData(const SUMOSAXAttributes &attrs, int objecttype)
Builds edge or lane base mean data collector using the given specification.
Definition: NLHandler.cpp:1316
bool myHaveWarnedAboutInvalidTLType
Definition: NLHandler.h:349
void addParam(const SUMOSAXAttributes &attrs)
Definition: NLHandler.cpp:639
void addConnection(const SUMOSAXAttributes &attrs)
adds a connection
Definition: NLHandler.cpp:1395
Builder of microsim-junctions and tls.
MSTLLogicControl::TLSLogicVariants & getTLLogic(const std::string &id) const
Returns a previously build tls logic.
void closeFunction()
closes a switching condition function to the traffic lights logic currently build
MSJunction * retrieve(const std::string id)
try to retrieve junction by id
const MSSimpleTrafficLightLogic::Phases & getLoadedPhases() const
return the phases loaded so far (for error reporting and cleanup)
void addPhase(MSPhaseDefinition *phase)
Adds a phase to the currently built traffic lights logic.
MSTLLogicControl & getTLLogicControlToUse() const
Returns the used tls control.
void addFunction(const std::string &id, int nArgs)
adds a switching condition function to the traffic lights logic currently build
const std::string & getActiveSubKey() const
Returns the active sub key.
bool addCondition(const std::string &id, const std::string &value)
Adds a condition to the currently built traffic lights logic.
void openJunction(const std::string &id, const std::string &key, const SumoXMLNodeType type, const Position pos, const PositionVector &shape, const std::vector< MSLane * > &incomingLanes, const std::vector< MSLane * > &internalLanes, const std::string &name)
Begins the processing of the named junction.
void addParam(const std::string &key, const std::string &value)
Adds a parameter.
void initJunctionLogic(const std::string &id)
Initialises a junction logic.
void initTrafficLightLogic(const std::string &id, const std::string &programID, TrafficLightType type, SUMOTime offset)
Begins the reading of a traffic lights logic.
const std::string & getActiveKey() const
Returns the active key.
void addAssignment(const std::string &id, const std::string &check, const std::string &value)
Adds an assignment to the currently built traffic lights logic.
void addLogicItem(int request, const std::string &response, const std::string &foes, bool cont)
Adds a logic item.
void closeJunction(const std::string &basePath)
Closes (ends) the processing of the current junction.
virtual void closeTrafficLightLogic(const std::string &basePath)
Ends the building of a traffic lights logic.
Position getLanePos(const std::string &poiID, const std::string &laneID, double lanePos, bool friendlyPos, double lanePosLat)
get position for a given laneID (Has to be implemented in all child)
Definition: NLHandler.cpp:1751
Builds trigger objects for microsim.
void parseAndBuildTractionSubstation(MSNet &net, const SUMOSAXAttributes &attrs)
Parses its values and builds a traction substation.
void addAccess(MSNet &net, const SUMOSAXAttributes &attrs)
Parses the values and adds an access point to the currently parsed stopping place.
void parseAndBuildOverheadWireSegment(MSNet &net, const SUMOSAXAttributes &attrs)
Parses its values and builds an overhead wire segment.
void parseAndBuildCalibrator(MSNet &net, const SUMOSAXAttributes &attrs, const std::string &base)
Parses his values and builds a mesoscopic or microscopic calibrator.
virtual void endParkingArea()
End a parking area.
void parseAndBuildLaneSpeedTrigger(MSNet &net, const SUMOSAXAttributes &attrs, const std::string &base)
Parses his values and builds a lane speed trigger.
void parseAndAddLotEntry(const SUMOSAXAttributes &attrs)
Parses his values and adds a lot entry to current parking area.
void updateParkingAreaDefaultCapacity()
updates the parkingArea default capacity
void buildVaporizer(const SUMOSAXAttributes &attrs)
Builds a vaporization.
void parseAndBuildRerouter(MSNet &net, const SUMOSAXAttributes &attrs)
Parses his values and builds a rerouter.
void parseAndBuildOverheadWireSection(MSNet &net, const SUMOSAXAttributes &attrs)
Parses its values and builds an overhead wire section.
void parseAndBuildChargingStation(MSNet &net, const SUMOSAXAttributes &attrs)
Parses his values and builds a charging station.
void parseAndBuildOverheadWireClamp(MSNet &net, const SUMOSAXAttributes &attrs)
Parses its values and builds an overhead wire clamp.
virtual void endStoppingPlace()
End a stopping place.
MSStoppingPlace * getCurrentStop()
void parseAndBuildStoppingPlace(MSNet &net, const SUMOSAXAttributes &attrs, const SumoXMLTag element)
Parses the values and builds a stopping places for busses, trains or container vehicles.
void parseAndBeginParkingArea(MSNet &net, const SUMOSAXAttributes &attrs)
Parses his values and builds a parking area.
const std::string & getID() const
Returns the id.
Definition: Named.h:74
T get(const std::string &id) const
Retrieves an item.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:60
An upper class for objects with additional parameters.
Definition: Parameterised.h:41
void clearParameter()
Clears the parameter map.
const Parameterised::Map & getParametersMap() const
Returns the inner key/value map.
virtual void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
void updateParameters(const Parameterised::Map &mapArg)
Adds or updates all given parameters from the map.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
static const Position INVALID
used to indicate that a position is valid
Definition: Position.h:322
A list of positions.
void closePolygon()
ensures that the last position equals the first
static RGBColor parseColor(std::string coldef)
Parses a color information.
Definition: RGBColor.cpp:239
virtual void myEndElement(int element)
Called when a closing tag occurs.
Encapsulated SAX-Attributes.
virtual std::string getString(int id, bool *isPresent=nullptr) const =0
Returns the string-value of the named (by its enum-value) attribute.
SUMOTime getOptPeriod(const char *objectid, bool &ok, SUMOTime defaultValue, bool report=true) const
Tries to read the SUMOTime 'period' attribute.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue=T(), bool report=true) const
Tries to read given attribute assuming it is an int.
SUMOTime getOptSUMOTimeReporting(int attr, const char *objectid, bool &ok, SUMOTime defaultValue, bool report=true) const
Tries to read given attribute assuming it is a SUMOTime.
virtual std::string getStringSecure(int id, const std::string &def) const =0
Returns the string-value of the named (by its enum-value) attribute.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
SUMOTime getPeriod(const char *objectid, bool &ok, bool report=true) const
Tries to read the SUMOTime 'period' attribute.
SUMOTime getSUMOTimeReporting(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is a SUMOTime.
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
static StringBijection< PersonMode > PersonModeValues
person modes
static StringBijection< LinkState > LinkStates
link states
static StringBijection< LinkDirection > LinkDirections
link directions
static std::string getJunctionIDFromInternalEdge(const std::string internalEdge)
return the junction id when given an edge of type internal, crossing or WalkingArea
const Polygons & getPolygons() const
Returns all polygons.
virtual bool addPolygon(const std::string &id, const std::string &type, const RGBColor &color, double layer, double angle, const std::string &imgFile, bool relativePath, const PositionVector &shape, bool geo, bool fill, double lineWidth, bool ignorePruning=false, const std::string &name=Shape::DEFAULT_NAME)
Builds a polygon using the given values and adds it to the container.
stop offset
T get(const std::string &str) const
std::vector< std::string > getVector()
return vector of strings
bool hasNext()
returns the information whether further substrings exist
std::string next()
returns the next substring when it exists. Otherwise the behaviour is undefined
static MMVersion toVersion(const std::string &sData)
parse a (network) version string
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.hpp:4451
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition: json.hpp:21884
edge type specific meso parameters
Definition: MESegment.h:55