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;
368  myLastParameterised.pop_back();
369  break;
370  case SUMO_TAG_BUS_STOP:
371  case SUMO_TAG_TRAIN_STOP:
375  myLastParameterised.pop_back();
376  break;
377  case SUMO_TAG_PREDECESSOR: // intended fall-through
378  case SUMO_TAG_FOE_INSERTION: // intended fall-through
379  case SUMO_TAG_INSERTION_PREDECESSOR: // intended fall-through
380  case SUMO_TAG_INSERTION_ORDER: // intended fall-through
382  myLastParameterised.pop_back();
383  break;
384  case SUMO_TAG_NET:
385  // build junction graph
386  for (JunctionGraph::iterator it = myJunctionGraph.begin(); it != myJunctionGraph.end(); ++it) {
387  MSEdge* edge = MSEdge::dictionary(it->first);
388  MSJunction* from = myJunctionControlBuilder.retrieve(it->second.first);
389  MSJunction* to = myJunctionControlBuilder.retrieve(it->second.second);
390  if (from == nullptr) {
391  WRITE_ERRORF(TL("Unknown from-node '%' for edge '%'."), it->second.first, it->first);
392  return;
393  }
394  if (to == nullptr) {
395  WRITE_ERRORF(TL("Unknown to-node '%' for edge '%'."), it->second.second, it->first);
396  return;
397  }
398  if (edge != nullptr) {
399  edge->setJunctions(from, to);
400  from->addOutgoing(edge);
401  to->addIncoming(edge);
402  }
403  }
404  myNetIsLoaded = true;
405  break;
406  default:
407  break;
408  }
410 }
411 
412 
413 
414 // ---- the root/edge - element
415 void
417  bool ok = true;
418  myCurrentIsBroken = false;
419  // get the id, report an error if not given or empty...
420  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
421  if (!ok) {
422  myCurrentIsBroken = true;
423  return;
424  }
425  // parse the function
427  if (!ok) {
428  myCurrentIsBroken = true;
429  return;
430  }
431  // omit internal edges if not wished
432  if (id[0] == ':') {
433  myHaveSeenInternalEdge = true;
436  return;
437  }
438  std::string junctionID = SUMOXMLDefinitions::getJunctionIDFromInternalEdge(id);
439  myJunctionGraph[id] = std::make_pair(junctionID, junctionID);
440  } else {
442  myJunctionGraph[id] = std::make_pair(
443  attrs.get<std::string>(SUMO_ATTR_FROM, id.c_str(), ok),
444  attrs.get<std::string>(SUMO_ATTR_TO, id.c_str(), ok));
445  }
446  if (!ok) {
447  myCurrentIsBroken = true;
448  return;
449  }
451  // get the street name
452  const std::string streetName = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
453  // get the edge type
454  const std::string edgeType = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
455  // get the edge priority (only for visualization)
456  const int priority = attrs.getOpt<int>(SUMO_ATTR_PRIORITY, id.c_str(), ok, -1); // default taken from netbuild/NBFrame option 'default.priority'
457  // get the bidi-edge
458  const std::string bidi = attrs.getOpt<std::string>(SUMO_ATTR_BIDI, id.c_str(), ok, "");
459  // get the kilometrage/mileage (for visualization and output)
460  const double distance = attrs.getOpt<double>(SUMO_ATTR_DISTANCE, id.c_str(), ok, 0);
461 
462  if (!ok) {
463  myCurrentIsBroken = true;
464  return;
465  }
466  //
467  try {
468  myEdgeControlBuilder.beginEdgeParsing(id, func, streetName, edgeType, priority, bidi, distance);
469  } catch (InvalidArgument& e) {
470  WRITE_ERROR(e.what());
471  myCurrentIsBroken = true;
472  }
473 
474  if (func == SumoXMLEdgeFunc::CROSSING) {
475  //get the crossingEdges attribute (to implement the other side of the road pushbutton)
476  const std::string crossingEdges = attrs.getOpt<std::string>(SUMO_ATTR_CROSSING_EDGES, id.c_str(), ok, "");
477  if (!crossingEdges.empty()) {
478  std::vector<std::string> crossingEdgesVector;
479  StringTokenizer edges(crossingEdges);
480  while (edges.hasNext()) {
481  crossingEdgesVector.push_back(edges.next());
482  }
483  myEdgeControlBuilder.addCrossingEdges(crossingEdgesVector);
484  }
485  }
488 }
489 
490 
491 void
493  myLastParameterised.clear();
494  // omit internal edges if not wished and broken edges
496  return;
497  }
498  try {
500  MSEdge::dictionary(e->getID(), e);
502  } catch (InvalidArgument& e) {
503  WRITE_ERROR(e.what());
504  }
505 }
506 
507 
508 // ---- the root/edge/lanes/lane - element
509 void
511  // omit internal edges if not wished and broken edges
513  return;
514  }
515  bool ok = true;
516  // get the id, report an error if not given or empty...
517  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
518  if (!ok) {
519  myCurrentIsBroken = true;
520  return;
521  }
522  const double maxSpeed = attrs.get<double>(SUMO_ATTR_SPEED, id.c_str(), ok);
523  const double friction = attrs.getOpt<double>(SUMO_ATTR_FRICTION, id.c_str(), ok, (double)(1.), false);
524  const double length = attrs.get<double>(SUMO_ATTR_LENGTH, id.c_str(), ok);
525  const std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, id.c_str(), ok, "", false);
526  const std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
527  const std::string changeLeftS = attrs.getOpt<std::string>(SUMO_ATTR_CHANGE_LEFT, id.c_str(), ok, "");
528  const std::string changeRightS = attrs.getOpt<std::string>(SUMO_ATTR_CHANGE_RIGHT, id.c_str(), ok, "");
529  const double width = attrs.getOpt<double>(SUMO_ATTR_WIDTH, id.c_str(), ok, SUMO_const_laneWidth);
530  const PositionVector shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok);
531  const PositionVector outlineShape = attrs.getOpt<PositionVector>(SUMO_ATTR_OUTLINESHAPE, id.c_str(), ok, PositionVector());
532  const int index = attrs.get<int>(SUMO_ATTR_INDEX, id.c_str(), ok);
533  const bool isRampAccel = attrs.getOpt<bool>(SUMO_ATTR_ACCELERATION, id.c_str(), ok, false);
534  const std::string type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
535  if (shape.size() < 2) {
536  WRITE_ERRORF(TL("Shape of lane '%' is broken.\n Can not build according edge."), id);
537  myCurrentIsBroken = true;
538  return;
539  }
540  const SVCPermissions permissions = parseVehicleClasses(allow, disallow, myNetworkVersion);
541  SVCPermissions changeLeft = parseVehicleClasses(changeLeftS, "", myNetworkVersion);
542  SVCPermissions changeRight = parseVehicleClasses(changeRightS, "", myNetworkVersion);
543  if (MSGlobals::gLefthand) {
544  // internally, changeLeft always checks for the higher lane index
545  // even though the higher lane index is to the right in a left-hand network
546  std::swap(changeLeft, changeRight);
547  }
548  if (permissions != SVCAll || changeLeft != SVCAll || changeRight != SVCAll) {
550  }
551  myCurrentIsBroken |= !ok;
552  if (!myCurrentIsBroken) {
553  try {
554  MSLane* lane = myEdgeControlBuilder.addLane(id, maxSpeed, friction, length, shape, width, permissions, changeLeft, changeRight, index, isRampAccel, type, outlineShape);
555  // insert the lane into the lane-dictionary, checking
556  if (!MSLane::dictionary(id, lane)) {
557  delete lane;
558  WRITE_ERRORF(TL("Another lane with the id '%' exists."), id);
559  myCurrentIsBroken = true;
560  myLastParameterised.push_back(nullptr);
561  } else {
562  myLastParameterised.push_back(lane);
563  }
564  } catch (InvalidArgument& e) {
565  WRITE_ERROR(e.what());
566  }
567  }
568 }
569 
570 
571 // ---- the root/junction - element
572 void
574  myCurrentIsBroken = false;
575  bool ok = true;
576  // get the id, report an error if not given or empty...
577  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
578  if (!ok) {
579  myCurrentIsBroken = true;
580  return;
581  }
582  PositionVector shape;
583  if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
584  // inner junctions have no shape
585  shape = attrs.getOpt<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok, PositionVector());
586  if (shape.size() > 2) {
587  shape.closePolygon();
588  }
589  }
590  double x = attrs.get<double>(SUMO_ATTR_X, id.c_str(), ok);
591  double y = attrs.get<double>(SUMO_ATTR_Y, id.c_str(), ok);
592  double z = attrs.getOpt<double>(SUMO_ATTR_Z, id.c_str(), ok, 0);
593  const SumoXMLNodeType type = attrs.get<SumoXMLNodeType>(SUMO_ATTR_TYPE, id.c_str(), ok);
594  std::string key = attrs.getOpt<std::string>(SUMO_ATTR_KEY, id.c_str(), ok, "");
595  std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
596  // incoming lanes
597  std::vector<MSLane*> incomingLanes;
598  parseLanes(id, attrs.getStringSecure(SUMO_ATTR_INCLANES, ""), incomingLanes, ok);
599  // internal lanes
600  std::vector<MSLane*> internalLanes;
602  parseLanes(id, attrs.getStringSecure(SUMO_ATTR_INTLANES, ""), internalLanes, ok);
603  }
604  if (!ok) {
605  myCurrentIsBroken = true;
606  } else {
607  try {
608  myJunctionControlBuilder.openJunction(id, key, type, Position(x, y, z), shape, incomingLanes, internalLanes, name);
609  } catch (InvalidArgument& e) {
610  WRITE_ERROR(e.what() + std::string("\n Can not build according junction."));
611  myCurrentIsBroken = true;
612  }
613  }
614 }
615 
616 
617 void
618 NLHandler::parseLanes(const std::string& junctionID,
619  const std::string& def, std::vector<MSLane*>& into, bool& ok) {
620  StringTokenizer st(def, " ");
621  while (ok && st.hasNext()) {
622  std::string laneID = st.next();
623  MSLane* lane = MSLane::dictionary(laneID);
624  if (!MSGlobals::gUsingInternalLanes && laneID[0] == ':') {
625  continue;
626  }
627  if (lane == nullptr) {
628  WRITE_ERRORF(TL("An unknown lane ('%') was tried to be set as incoming to junction '%'."), laneID, junctionID);
629  ok = false;
630  continue;
631  }
632  into.push_back(lane);
633  }
634 }
635 // ----
636 
637 void
639  bool ok = true;
640  const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
641  // circumventing empty string test
642  const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
643  if (myLastParameterised.size() > 0 && myLastParameterised.back() != nullptr) {
644  myLastParameterised.back()->setParameter(key, val);
645  }
646  // set
647  if (ok && myAmParsingTLLogicOrJunction) {
648  assert(key != "");
650  }
651 }
652 
653 
654 void
656  myCurrentIsBroken = false;
657  bool ok = true;
658  // get the id, report an error if not given or empty...
659  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
660  if (!ok) {
661  myCurrentIsBroken = true;
662  return;
663  }
664  SUMOTime refTime = attrs.getOptSUMOTimeReporting(SUMO_ATTR_REF_TIME, id.c_str(), ok, 0);
665  SUMOTime period = attrs.getOptSUMOTimeReporting(SUMO_ATTR_PERIOD, id.c_str(), ok, 0);
666  std::string startProg = attrs.get<std::string>(SUMO_ATTR_START_PROG, id.c_str(), ok);
667  if (!ok) {
668  myCurrentIsBroken = true;
669  }
670  if (!myCurrentIsBroken) {
671  myCurrentWAUTID = id;
672  try {
673  myJunctionControlBuilder.getTLLogicControlToUse().addWAUT(refTime, id, startProg, period);
674  } catch (InvalidArgument& e) {
675  WRITE_ERROR(e.what());
676  myCurrentIsBroken = true;
677  }
678  }
679 }
680 
681 
682 void
684  bool ok = true;
686  std::string to = attrs.get<std::string>(SUMO_ATTR_TO, myCurrentWAUTID.c_str(), ok);
687  if (!ok) {
688  myCurrentIsBroken = true;
689  }
690  if (!myCurrentIsBroken) {
691  try {
693  } catch (InvalidArgument& e) {
694  WRITE_ERROR(e.what());
695  myCurrentIsBroken = true;
696  }
697  }
698 }
699 
700 
701 void
703  bool ok = true;
704  std::string wautID = attrs.get<std::string>(SUMO_ATTR_WAUT_ID, nullptr, ok);
705  std::string junctionID = attrs.get<std::string>(SUMO_ATTR_JUNCTION_ID, nullptr, ok);
706  std::string procedure = attrs.getOpt<std::string>(SUMO_ATTR_PROCEDURE, nullptr, ok, "");
707  bool synchron = attrs.getOpt<bool>(SUMO_ATTR_SYNCHRON, nullptr, ok, false);
708  if (!ok) {
709  myCurrentIsBroken = true;
710  }
711  try {
712  if (!myCurrentIsBroken) {
713  myJunctionControlBuilder.getTLLogicControlToUse().addWAUTJunction(wautID, junctionID, procedure, synchron);
714  }
715  } catch (InvalidArgument& e) {
716  WRITE_ERROR(e.what());
717  myCurrentIsBroken = true;
718  }
719 }
720 
721 
722 void
724  if (myCurrentIsBroken) {
725  return;
726  }
727  bool ok = true;
728  int request = attrs.get<int>(SUMO_ATTR_INDEX, nullptr, ok);
729  bool cont = false;
730  cont = attrs.getOpt<bool>(SUMO_ATTR_CONT, nullptr, ok, false);
731  std::string response = attrs.get<std::string>(SUMO_ATTR_RESPONSE, nullptr, ok);
732  std::string foes = attrs.get<std::string>(SUMO_ATTR_FOES, nullptr, ok);
733  if (!ok) {
734  return;
735  }
736  // store received information
737  if (request >= 0 && response.length() > 0) {
738  try {
739  myJunctionControlBuilder.addLogicItem(request, response, foes, cont);
740  } catch (InvalidArgument& e) {
741  WRITE_ERROR(e.what());
742  }
743  }
744 }
745 
746 
747 void
749  if (myCurrentIsBroken) {
750  return;
751  }
753  bool ok = true;
754  // we either a have a junction or a legacy network with ROWLogic
755  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
756  if (ok) {
758  }
759 }
760 
761 
762 void
764  myCurrentIsBroken = false;
766  bool ok = true;
767  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
768  std::string programID = attrs.getOpt<std::string>(SUMO_ATTR_PROGRAMID, id.c_str(), ok, "<unknown>");
770  std::string typeS;
771  if (myJunctionControlBuilder.getTLLogicControlToUse().get(id, programID) == nullptr) {
772  // SUMO_ATTR_TYPE is not needed when only modifying the offset of an
773  // existing program
774  typeS = attrs.get<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok);
775  if (!ok) {
776  myCurrentIsBroken = true;
777  return;
778  }
779  if (SUMOXMLDefinitions::TrafficLightTypes.hasString(typeS)) {
781  } else {
782  WRITE_ERRORF(TL("Traffic light '%' has unknown type '%'."), id, typeS);
783  }
786  WRITE_WARNINGF(TL("Traffic light type '%' cannot be used in mesoscopic simulation. Using '%' as fallback."), toString(type), toString(TrafficLightType::STATIC));
788  }
790  }
791  }
792  //
793  const SUMOTime offset = attrs.getOptSUMOTimeReporting(SUMO_ATTR_OFFSET, id.c_str(), ok, 0);
794  if (!ok) {
795  myCurrentIsBroken = true;
796  return;
797  }
798  myJunctionControlBuilder.initTrafficLightLogic(id, programID, type, offset);
799 }
800 
801 
802 void
804  // try to get the phase definition
805  bool ok = true;
806  const std::string& id = myJunctionControlBuilder.getActiveKey();
808 
810  const std::string state = attrs.get<std::string>(SUMO_ATTR_STATE, nullptr, ok);
811  if (duration == 0) {
812  WRITE_ERROR("Duration of phase " + toString(myJunctionControlBuilder.getLoadedPhases().size())
813  + " for tlLogic '" + myJunctionControlBuilder.getActiveKey()
814  + "' program '" + myJunctionControlBuilder.getActiveSubKey() + "' is zero.");
815  return;
816  }
817  if (!ok) {
818  return;
819  }
820  MSPhaseDefinition* phase = new MSPhaseDefinition(duration, state);
821 
822  // if the traffic light is an actuated traffic light, try to get
823  // the minimum and maximum durations
824  phase->minDuration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MINDURATION, id.c_str(), ok, duration);
825  // if minDur is set but not maxDur, assume high maxDur (avoid using the absolute max in case we do some arithmetic later)
826  SUMOTime defaultMaxDur = attrs.hasAttribute(SUMO_ATTR_MINDURATION) ? std::numeric_limits<int>::max() : duration;
827  phase->maxDuration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MAXDURATION, id.c_str(), ok, defaultMaxDur);
828  phase->earliestEnd = attrs.getOptSUMOTimeReporting(SUMO_ATTR_EARLIEST_END, id.c_str(), ok, tDefault);
829  phase->latestEnd = attrs.getOptSUMOTimeReporting(SUMO_ATTR_LATEST_END, id.c_str(), ok, tDefault);
830  phase->nextPhases = attrs.getOpt<std::vector<int> >(SUMO_ATTR_NEXT, id.c_str(), ok);
831  phase->earlyTarget = attrs.getOpt<std::string>(SUMO_ATTR_EARLY_TARGET, id.c_str(), ok);
832  phase->finalTarget = attrs.getOpt<std::string>(SUMO_ATTR_FINAL_TARGET, id.c_str(), ok);
833  phase->name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok);
834 
835  phase->vehext = attrs.getOptSUMOTimeReporting(SUMO_ATTR_VEHICLEEXTENSION, id.c_str(), ok, tDefault);
836  phase->yellow = attrs.getOptSUMOTimeReporting(SUMO_ATTR_YELLOW, id.c_str(), ok, tDefault);
837  phase->red = attrs.getOptSUMOTimeReporting(SUMO_ATTR_RED, id.c_str(), ok, tDefault);
838 
839  if (attrs.hasAttribute(SUMO_ATTR_TYPE)) {
840  //SOTL attributes
841  //If the type attribute is not present, the parsed phase is of type "undefined" (MSPhaseDefinition constructor),
842  //in this way SOTL traffic light logic can recognize the phase as unsuitable or decides other
843  //behaviors. See SOTL traffic light logic implementations.
844  std::string phaseTypeString;
845  try {
846  phaseTypeString = attrs.get<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, false);
847  } catch (EmptyData&) {
848  MsgHandler::getWarningInstance()->inform("Empty type definition. Assuming phase type as SUMOSOTL_TagAttrDefinitions::SOTL_ATTL_TYPE_TRANSIENT");
849  phase->myTransientNotDecisional = false;
850  }
851  if (phaseTypeString.find("decisional") != std::string::npos) {
852  phase->myTransientNotDecisional = false;
853  } else if (phaseTypeString.find("transient") != std::string::npos) {
854  phase->myTransientNotDecisional = true;
855  } else {
856  MsgHandler::getWarningInstance()->inform("SOTL_ATTL_TYPE_DECISIONAL nor SOTL_ATTL_TYPE_TRANSIENT. Assuming phase type as SUMOSOTL_TagAttrDefinitions::SOTL_ATTL_TYPE_TRANSIENT");
857  phase->myTransientNotDecisional = false;
858  }
859  phase->myCommit = (phaseTypeString.find("commit") != std::string::npos);
860 
861  if (phaseTypeString.find("target") != std::string::npos) {
862  std::string delimiter(" ,;");
863  //Phase declared as target, getting targetLanes attribute
864  try {
866  } catch (EmptyData&) {
867  MsgHandler::getErrorInstance()->inform("Missing targetLane definition for the target phase.");
868  delete phase;
869  return;
870  }
871  }
872  }
873 
874  if (phase->maxDuration < phase->minDuration) {
875  WRITE_WARNINGF(TL("maxDur % should not be smaller than minDir % in phase of tlLogic %"), phase->maxDuration, phase->minDuration, id);
876  phase->maxDuration = phase->duration;
877  }
878 
879  phase->myLastSwitch = string2time(OptionsCont::getOptions().getString("begin")) - 1; // SUMOTime-option
881 }
882 
883 
884 void
886  bool ok = true;
887  const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
888  const std::string value = attrs.get<std::string>(SUMO_ATTR_VALUE, id.c_str(), ok);
889  if (!myJunctionControlBuilder.addCondition(id, value)) {
890  WRITE_ERRORF(TL("Duplicate condition '%' in tlLogic '%'"), id, myJunctionControlBuilder.getActiveKey());
891  }
892 }
893 
894 
895 void
897  bool ok = true;
898  const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
899  const std::string check = attrs.get<std::string>(SUMO_ATTR_CHECK, nullptr, ok);
900  const std::string value = attrs.get<std::string>(SUMO_ATTR_VALUE, id.c_str(), ok);
901  myJunctionControlBuilder.addAssignment(id, check, value);
902 }
903 
904 
905 void
907  bool ok = true;
908  const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
909  const int nArgs = attrs.get<int>(SUMO_ATTR_NARGS, nullptr, ok);
911 }
912 
913 void
916 }
917 
918 void
920  myCurrentIsBroken = false;
921  bool ok = true;
922  // get the id, report an error if not given or empty...
923  const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
924  if (!ok) {
925  myCurrentIsBroken = true;
926  return;
927  }
928  const SUMOTime period = attrs.getOptPeriod(id.c_str(), ok, SUMOTime_MAX_PERIOD);
929  const double position = attrs.get<double>(SUMO_ATTR_POSITION, id.c_str(), ok);
930  const double length = attrs.getOpt<double>(SUMO_ATTR_LENGTH, id.c_str(), ok, 0);
931  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
932  const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
933  const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
934  const std::string nextEdges = attrs.getOpt<std::string>(SUMO_ATTR_NEXT_EDGES, id.c_str(), ok, "");
935  const std::string lane = attrs.get<std::string>(SUMO_ATTR_LANE, id.c_str(), ok);
936  const std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
937  const std::string detectPersonsString = attrs.getOpt<std::string>(SUMO_ATTR_DETECT_PERSONS, id.c_str(), ok, "");
938  int detectPersons = 0;
939  for (std::string mode : StringTokenizer(detectPersonsString).getVector()) {
940  if (SUMOXMLDefinitions::PersonModeValues.hasString(mode)) {
941  detectPersons |= (int)SUMOXMLDefinitions::PersonModeValues.get(mode);
942  } else {
943  WRITE_ERRORF(TL("Invalid person mode '%' in E1 detector definition '%'"), mode, id);
944  myCurrentIsBroken = true;
945  return;
946  }
947  }
948  if (!ok) {
949  myCurrentIsBroken = true;
950  return;
951  }
952  try {
953  Parameterised* det = myDetectorBuilder.buildInductLoop(id, lane, position, length, period,
955  friendlyPos, name, vTypes, nextEdges, detectPersons);
956  myLastParameterised.push_back(det);
957  } catch (InvalidArgument& e) {
958  myCurrentIsBroken = true;
959  WRITE_ERROR(e.what());
960  } catch (IOError& e) {
961  myCurrentIsBroken = true;
962  WRITE_ERROR(e.what());
963  }
964 }
965 
966 
967 void
969  myCurrentIsBroken = false;
970  bool ok = true;
971  // get the id, report an error if not given or empty...
972  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
973  if (!ok) {
974  myCurrentIsBroken = true;
975  return;
976  }
977  const double position = attrs.get<double>(SUMO_ATTR_POSITION, id.c_str(), ok);
978  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
979  const std::string lane = attrs.get<std::string>(SUMO_ATTR_LANE, id.c_str(), ok);
980  const std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
981  const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
982  const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
983  const std::string nextEdges = attrs.getOpt<std::string>(SUMO_ATTR_NEXT_EDGES, id.c_str(), ok, "");
984  if (!ok) {
985  myCurrentIsBroken = true;
986  return;
987  }
988  try {
989  Parameterised* det = myDetectorBuilder.buildInstantInductLoop(id, lane, position, FileHelpers::checkForRelativity(file, getFileName()), friendlyPos, name, vTypes, nextEdges);
990  myLastParameterised.push_back(det);
991  } catch (InvalidArgument& e) {
992  WRITE_ERROR(e.what());
993  } catch (IOError& e) {
994  WRITE_ERROR(e.what());
995  }
996  myCurrentIsBroken = true;
997 }
998 
999 
1000 void
1002  WRITE_WARNING(TL("VTypeProbes are deprecated. Use fcd-output devices (assigned to the vType) instead."));
1003  bool ok = true;
1004  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1005  SUMOTime period = attrs.getOptPeriod(id.c_str(), ok, SUMOTime_MAX_PERIOD);
1006  std::string type = attrs.getStringSecure(SUMO_ATTR_TYPE, "");
1007  std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1008  if (!ok) {
1009  return;
1010  }
1011  try {
1013  } catch (InvalidArgument& e) {
1014  WRITE_ERROR(e.what());
1015  } catch (IOError& e) {
1016  WRITE_ERROR(e.what());
1017  }
1018 }
1019 
1020 
1021 void
1023  bool ok = true;
1024  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1025  SUMOTime period = attrs.getOptPeriod(id.c_str(), ok, SUMOTime_MAX_PERIOD);
1026  SUMOTime begin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, id.c_str(), ok, -1);
1027  std::string edge = attrs.get<std::string>(SUMO_ATTR_EDGE, id.c_str(), ok);
1028  std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1029  const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
1030  if (!ok) {
1031  return;
1032  }
1033  try {
1034  myDetectorBuilder.buildRouteProbe(id, edge, period, begin,
1035  FileHelpers::checkForRelativity(file, getFileName()), vTypes);
1036  } catch (InvalidArgument& e) {
1037  WRITE_ERROR(e.what());
1038  } catch (IOError& e) {
1039  WRITE_ERROR(e.what());
1040  }
1041 }
1042 
1043 
1044 
1045 void
1047  myCurrentIsBroken = false;
1048  // check whether this is a detector connected to a tls and optionally to a link
1049  bool ok = true;
1050  const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1051  const std::string lsaid = attrs.getOpt<std::string>(SUMO_ATTR_TLID, id.c_str(), ok, "");
1052  const std::string toLane = attrs.getOpt<std::string>(SUMO_ATTR_TO, id.c_str(), ok, "");
1053  const SUMOTime haltingTimeThreshold = attrs.getOptSUMOTimeReporting(SUMO_ATTR_HALTING_TIME_THRESHOLD, id.c_str(), ok, TIME2STEPS(1));
1054  const double haltingSpeedThreshold = attrs.getOpt<double>(SUMO_ATTR_HALTING_SPEED_THRESHOLD, id.c_str(), ok, 5.0f / 3.6f);
1055  const double jamDistThreshold = attrs.getOpt<double>(SUMO_ATTR_JAM_DIST_THRESHOLD, id.c_str(), ok, 10.0f);
1056  double position = attrs.getOpt<double>(SUMO_ATTR_POSITION, id.c_str(), ok, std::numeric_limits<double>::max());
1057  const double length = attrs.getOpt<double>(SUMO_ATTR_LENGTH, id.c_str(), ok, std::numeric_limits<double>::max());
1058  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
1059  const bool showDetector = attrs.getOpt<bool>(SUMO_ATTR_SHOW_DETECTOR, id.c_str(), ok, true);
1060  const std::string contStr = attrs.getOpt<std::string>(SUMO_ATTR_CONT, id.c_str(), ok, "");
1061  if (contStr != "") {
1062  WRITE_WARNINGF(TL("Ignoring deprecated argument 'cont' for E2 detector '%'"), id);
1063  }
1064  std::string lane = attrs.getOpt<std::string>(SUMO_ATTR_LANE, id.c_str(), ok, "");
1065  const std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1066  const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
1067  const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
1068  const std::string nextEdges = attrs.getOpt<std::string>(SUMO_ATTR_NEXT_EDGES, id.c_str(), ok, "");
1069 
1070  double endPosition = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, id.c_str(), ok, std::numeric_limits<double>::max());
1071  const std::string lanes = attrs.getOpt<std::string>(SUMO_ATTR_LANES, id.c_str(), ok, ""); // lanes has priority to lane
1072  const std::string detectPersonsString = attrs.getOpt<std::string>(SUMO_ATTR_DETECT_PERSONS, id.c_str(), ok, "");
1073  int detectPersons = 0;
1074  for (std::string mode : StringTokenizer(detectPersonsString).getVector()) {
1075  if (SUMOXMLDefinitions::PersonModeValues.hasString(mode)) {
1076  detectPersons |= (int)SUMOXMLDefinitions::PersonModeValues.get(mode);
1077  } else {
1078  WRITE_ERRORF(TL("Invalid person mode '%' in E2 detector definition '%'"), mode, id);
1079  myCurrentIsBroken = true;
1080  return;
1081  }
1082  }
1083  if (!ok) {
1084  myCurrentIsBroken = true;
1085  return;
1086  }
1087 
1088  bool lanesGiven = lanes != "";
1089  bool laneGiven = lane != "";
1090  if (!(lanesGiven || laneGiven)) {
1091  // in absence of any lane-specification assume specification by id
1092  WRITE_WARNING(TL("Trying to specify detector's lane by the given id since the argument 'lane' is missing."))
1093  lane = id;
1094  laneGiven = true;
1095  }
1096  bool lengthGiven = length != std::numeric_limits<double>::max();
1097  bool posGiven = position != std::numeric_limits<double>::max();
1098  bool endPosGiven = endPosition != std::numeric_limits<double>::max();
1099  bool lsaGiven = lsaid != "";
1100  bool toLaneGiven = toLane != "";
1101 
1102  MSLane* clane = nullptr;
1103  std::vector<MSLane*> clanes;
1104  if (lanesGiven) {
1105  // If lanes is given, endPos and startPos are required. lane, and length are ignored
1106  std::string seps = " ,\t\n";
1107  StringTokenizer st = StringTokenizer(lanes, seps, true);
1108 // std::cout << "Parsing lanes..." << std::endl;
1109  while (st.hasNext()) {
1110  std::string nextLaneID = st.next();
1111 // std::cout << "Next: " << nextLaneID << std::endl;
1112  if (nextLaneID.find_first_of(seps) != nextLaneID.npos) {
1113  continue;
1114  }
1115  clane = myDetectorBuilder.getLaneChecking(nextLaneID, SUMO_TAG_E2DETECTOR, id);
1116  clanes.push_back(clane);
1117  }
1118  if (clanes.size() == 0) {
1119  throw InvalidArgument("Malformed argument 'lanes' for E2Detector '" + id + "'.\nSpecify 'lanes' as a sequence of lane-IDs separated by whitespace or comma (',')");
1120  }
1121  if (laneGiven) {
1122  WRITE_WARNING("Ignoring argument 'lane' for E2Detector '" + id + "' since argument 'lanes' was given.\n"
1123  "Usage combinations for positional specification: [lane, pos, length], [lane, endPos, length], or [lanes, pos, endPos]");
1124  }
1125  if (lengthGiven) {
1126  WRITE_WARNING("Ignoring argument 'length' for E2Detector '" + id + "' since argument 'lanes' was given.\n"
1127  "Usage combinations for positional specification: [lane, pos, length], [lane, endPos, length], or [lanes, pos, endPos]");
1128  }
1129  if (!posGiven) {
1130  // assuming start pos == lane start
1131  position = 0;
1132  WRITE_WARNINGF(TL("Missing argument 'pos' for E2Detector '%'. Assuming detector start == lane start of lane '%'."), id, clanes[0]->getID());
1133  }
1134  if (!endPosGiven) {
1135  // assuming end pos == lane end
1136  endPosition = clanes[clanes.size() - 1]->getLength();
1137  WRITE_WARNINGF(TL("Missing argument 'endPos' for E2Detector '%'. Assuming detector end == lane end of lane '%'."), id, clanes[clanes.size() - 1]->getID());
1138  }
1139 
1140  } else {
1141  if (!laneGiven) {
1142  std::stringstream ss;
1143  ss << "Missing argument 'lane' for E2Detector '" << id << "'."
1144  << "\nUsage combinations for positional specification: [lane, pos, length], [lane, endPos, length], or [lanes, pos, endPos]";
1145  throw InvalidArgument(ss.str());
1146  }
1148 
1149  if (posGiven) {
1150  // start pos is given
1151  if (endPosGiven && lengthGiven) {
1152  std::stringstream ss;
1153  ss << "Ignoring argument 'endPos' for E2Detector '" << id << "' since argument 'pos' was given."
1154  << "\nUsage combinations for positional specification: [lane, pos, length], [lane, endPos, length], or [lanes, pos, endPos]";
1155  WRITE_WARNING(ss.str());
1156  endPosition = std::numeric_limits<double>::max();
1157  }
1158  if (!lengthGiven && !endPosGiven) {
1159  std::stringstream ss;
1160  ss << "Missing arguments 'length'/'endPos' for E2Detector '" << id << "'. Assuming detector end == lane end of lane '" << lane << "'.";
1161  WRITE_WARNING(ss.str());
1162  endPosition = clane->getLength();
1163  }
1164  } else if (endPosGiven) {
1165  // endPos is given, pos is not given
1166  if (!lengthGiven) {
1167  std::stringstream ss;
1168  ss << "Missing arguments 'length'/'pos' for E2Detector '" << id << "'. Assuming detector start == lane start of lane '" << lane << "'.";
1169  WRITE_WARNING(ss.str());
1170  }
1171  } else {
1172  std::stringstream ss;
1173  if (lengthGiven && fabs(length - clane->getLength()) > NUMERICAL_EPS) {
1174  ss << "Incomplete positional specification for E2Detector '" << id << "'."
1175  << "\nUsage combinations for positional specification: [lane, pos, length], [lane, endPos, length], or [lanes, pos, endPos]";
1176  throw InvalidArgument(ss.str());
1177  }
1178  endPosition = clane->getLength();
1179  position = 0;
1180  ss << "Missing arguments 'pos'/'endPos' for E2Detector '" << id << "'. Assuming that the detector covers the whole lane '" << lane << "'.";
1181  WRITE_WARNING(ss.str());
1182  }
1183  }
1184 
1185  // Period
1186 
1187  SUMOTime period;
1188  if (!lsaGiven) {
1189  period = attrs.getOptPeriod(id.c_str(), ok, SUMOTime_MAX_PERIOD);
1190  if (!ok) {
1191  myCurrentIsBroken = true;
1192  return;
1193  }
1194  } else {
1195  period = attrs.getPeriod(id.c_str(), ok, false);
1196  }
1197 
1198  // TLS
1199  MSTLLogicControl::TLSLogicVariants* tlls = nullptr;
1200  if (lsaGiven) {
1201  tlls = &myJunctionControlBuilder.getTLLogic(lsaid);
1202  if (tlls->getActive() == nullptr) {
1203  throw InvalidArgument("The detector '" + id + "' refers to an unknown lsa '" + lsaid + "'.");
1204  }
1205  if (period != -1) {
1206  WRITE_WARNINGF(TL("Ignoring argument 'period' for E2Detector '%' since argument 'tl' was given."), id);
1207  period = -1;
1208  }
1209  }
1210 
1211  // Link
1212  MSLane* cToLane = nullptr;
1213  if (toLaneGiven) {
1214  cToLane = myDetectorBuilder.getLaneChecking(toLane, SUMO_TAG_E2DETECTOR, id);
1215  }
1216 
1217  // File
1218  std::string filename;
1219  try {
1220  filename = FileHelpers::checkForRelativity(file, getFileName());
1221  } catch (IOError& e) {
1222  WRITE_ERROR(e.what());
1223  }
1224 
1225  Parameterised* det;
1226  // Build detector
1227  if (lanesGiven) {
1228  // specification by a lane sequence
1229  det = myDetectorBuilder.buildE2Detector(id, clanes, position, endPosition, filename, period,
1230  haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold,
1231  name, vTypes, nextEdges, detectPersons, friendlyPos, showDetector,
1232  tlls, cToLane);
1233  } else {
1234  // specification by start or end lane
1235  det = myDetectorBuilder.buildE2Detector(id, clane, position, endPosition, length, filename, period,
1236  haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold,
1237  name, vTypes, nextEdges, detectPersons, friendlyPos, showDetector,
1238  tlls, cToLane);
1239  }
1240  myLastParameterised.push_back(det);
1241 }
1242 
1243 
1244 void
1246  myCurrentIsBroken = false;
1247  bool ok = true;
1248  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1249  const SUMOTime period = attrs.getOptPeriod(id.c_str(), ok, SUMOTime_MAX_PERIOD);
1250  const SUMOTime haltingTimeThreshold = attrs.getOptSUMOTimeReporting(SUMO_ATTR_HALTING_TIME_THRESHOLD, id.c_str(), ok, TIME2STEPS(1));
1251  const double haltingSpeedThreshold = attrs.getOpt<double>(SUMO_ATTR_HALTING_SPEED_THRESHOLD, id.c_str(), ok, 5.0f / 3.6f);
1252  const std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1253  const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
1254  const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
1255  const std::string nextEdges = attrs.getOpt<std::string>(SUMO_ATTR_NEXT_EDGES, id.c_str(), ok, "");
1256  const bool openEntry = attrs.getOpt<bool>(SUMO_ATTR_OPEN_ENTRY, id.c_str(), ok, false);
1257  const bool expectArrival = attrs.getOpt<bool>(SUMO_ATTR_EXPECT_ARRIVAL, id.c_str(), ok, false);
1258  const std::string detectPersonsString = attrs.getOpt<std::string>(SUMO_ATTR_DETECT_PERSONS, id.c_str(), ok, "");
1259  int detectPersons = 0;
1260  for (std::string mode : StringTokenizer(detectPersonsString).getVector()) {
1261  if (SUMOXMLDefinitions::PersonModeValues.hasString(mode)) {
1262  detectPersons |= (int)SUMOXMLDefinitions::PersonModeValues.get(mode);
1263  } else {
1264  WRITE_ERRORF(TL("Invalid person mode '%' in E3 detector definition '%'"), mode, id);
1265  myCurrentIsBroken = true;
1266  return;
1267  }
1268  }
1269  if (!ok) {
1270  myCurrentIsBroken = true;
1271  return;
1272  }
1273  try {
1276  period, haltingSpeedThreshold, haltingTimeThreshold, name, vTypes, nextEdges, detectPersons, openEntry, expectArrival);
1277  myLastParameterised.push_back(det);
1278  } catch (InvalidArgument& e) {
1279  myCurrentIsBroken = true;
1280  WRITE_ERROR(e.what());
1281  } catch (IOError& e) {
1282  myCurrentIsBroken = true;
1283  WRITE_ERROR(e.what());
1284  }
1285 }
1286 
1287 
1288 void
1290  bool ok = true;
1291  const double position = attrs.get<double>(SUMO_ATTR_POSITION, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
1292  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, myDetectorBuilder.getCurrentE3ID().c_str(), ok, false);
1293  const std::string lane = attrs.get<std::string>(SUMO_ATTR_LANE, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
1294  if (!ok) {
1295  return;
1296  }
1297  myDetectorBuilder.addE3Entry(lane, position, friendlyPos);
1298 }
1299 
1300 
1301 void
1303  bool ok = true;
1304  const double position = attrs.get<double>(SUMO_ATTR_POSITION, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
1305  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, myDetectorBuilder.getCurrentE3ID().c_str(), ok, false);
1306  const std::string lane = attrs.get<std::string>(SUMO_ATTR_LANE, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
1307  if (!ok) {
1308  return;
1309  }
1310  myDetectorBuilder.addE3Exit(lane, position, friendlyPos);
1311 }
1312 
1313 
1314 void
1315 NLHandler::addEdgeLaneMeanData(const SUMOSAXAttributes& attrs, int objecttype) {
1316  bool ok = true;
1317  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1318  const double maxTravelTime = attrs.getOpt<double>(SUMO_ATTR_MAX_TRAVELTIME, id.c_str(), ok, 100000);
1319  const double minSamples = attrs.getOpt<double>(SUMO_ATTR_MIN_SAMPLES, id.c_str(), ok, 0);
1320  const double haltingSpeedThreshold = attrs.getOpt<double>(SUMO_ATTR_HALTING_SPEED_THRESHOLD, id.c_str(), ok, POSITION_EPS);
1321  const std::string excludeEmpty = attrs.getOpt<std::string>(SUMO_ATTR_EXCLUDE_EMPTY, id.c_str(), ok, "false");
1322  const bool withInternal = attrs.getOpt<bool>(SUMO_ATTR_WITH_INTERNAL, id.c_str(), ok, false);
1323  const bool trackVehicles = attrs.getOpt<bool>(SUMO_ATTR_TRACK_VEHICLES, id.c_str(), ok, false);
1324  const std::string detectPersonsString = attrs.getOpt<std::string>(SUMO_ATTR_DETECT_PERSONS, id.c_str(), ok, "");
1325  const std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1326  const std::string type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "performance");
1327  std::string vtypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
1328  const std::string writeAttributes = attrs.getOpt<std::string>(SUMO_ATTR_WRITE_ATTRIBUTES, id.c_str(), ok, "");
1329  const SUMOTime period = attrs.getOptPeriod(id.c_str(), ok, -1);
1330  const SUMOTime begin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, id.c_str(), ok, string2time(OptionsCont::getOptions().getString("begin")));
1331  const SUMOTime end = attrs.getOptSUMOTimeReporting(SUMO_ATTR_END, id.c_str(), ok, string2time(OptionsCont::getOptions().getString("end")));
1332  std::vector<std::string> edgeIDs = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_EDGES, id.c_str(), ok);
1333  const std::string edgesFile = attrs.getOpt<std::string>(SUMO_ATTR_EDGESFILE, id.c_str(), ok, "");
1334  const bool aggregate = attrs.getOpt<bool>(SUMO_ATTR_AGGREGATE, id.c_str(), ok, false);
1335  if (!ok) {
1336  return;
1337  }
1338  int detectPersons = 0;
1339  for (std::string mode : StringTokenizer(detectPersonsString).getVector()) {
1340  if (SUMOXMLDefinitions::PersonModeValues.hasString(mode)) {
1341  detectPersons |= (int)SUMOXMLDefinitions::PersonModeValues.get(mode);
1342  } else {
1343  WRITE_ERRORF(TL("Invalid person mode '%' in edgeData definition '%'"), mode, id);
1344  return;
1345  }
1346  }
1347  if (edgesFile != "") {
1348  std::ifstream strm(edgesFile.c_str());
1349  if (!strm.good()) {
1350  throw ProcessError("Could not load names of edges for edgeData definition '" + id + "' from '" + edgesFile + "'.");
1351  }
1352  while (strm.good()) {
1353  std::string name;
1354  strm >> name;
1355  // maybe we're loading an edge-selection
1356  if (StringUtils::startsWith(name, "edge:")) {
1357  edgeIDs.push_back(name.substr(5));
1358  } else if (name != "") {
1359  edgeIDs.push_back(name);
1360  }
1361  }
1362  }
1363  std::vector<MSEdge*> edges;
1364  for (const std::string& edgeID : edgeIDs) {
1365  MSEdge* edge = MSEdge::dictionary(edgeID);
1366  if (edge == nullptr) {
1367  WRITE_ERRORF(TL("Unknown edge '%' in edgeData definition '%'"), edgeID, id);
1368  return;
1369  }
1370  edges.push_back(edge);
1371  }
1372  bool useLanes = objecttype == SUMO_TAG_MEANDATA_LANE;
1373  if (useLanes && MSGlobals::gUseMesoSim && !OptionsCont::getOptions().getBool("meso-lane-queue")) {
1374  WRITE_WARNINGF(TL("LaneData '%' requested for mesoscopic simulation but --meso-lane-queue is not active. Falling back to edgeData."), id);
1375  useLanes = false;
1376  }
1377  try {
1378  myDetectorBuilder.createEdgeLaneMeanData(id, period, begin, end,
1379  type, useLanes,
1380  // equivalent to TplConvert::_2bool used in SUMOSAXAttributes::getBool
1381  excludeEmpty[0] != 't' && excludeEmpty[0] != 'T' && excludeEmpty[0] != '1' && excludeEmpty[0] != 'x',
1382  excludeEmpty == "defaults", withInternal, trackVehicles, detectPersons,
1383  maxTravelTime, minSamples, haltingSpeedThreshold, vtypes, writeAttributes, edges, aggregate,
1385  } catch (InvalidArgument& e) {
1386  WRITE_ERROR(e.what());
1387  } catch (IOError& e) {
1388  WRITE_ERROR(e.what());
1389  }
1390 }
1391 
1392 
1393 void
1395  bool ok = true;
1396  const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
1397  const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
1398  if (!MSGlobals::gUsingInternalLanes && (fromID[0] == ':' || toID[0] == ':')) {
1399  std::string tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, nullptr, ok, "");
1400  if (tlID != "") {
1401  int tlLinkIdx = attrs.get<int>(SUMO_ATTR_TLLINKINDEX, nullptr, ok);
1403  }
1404  return;
1405  }
1406 
1407  myCurrentLink = nullptr;
1408  try {
1409  const int fromLaneIdx = attrs.get<int>(SUMO_ATTR_FROM_LANE, nullptr, ok);
1410  const int toLaneIdx = attrs.get<int>(SUMO_ATTR_TO_LANE, nullptr, ok);
1411  LinkDirection dir = parseLinkDir(attrs.get<std::string>(SUMO_ATTR_DIR, nullptr, ok));
1412  LinkState state = parseLinkState(attrs.get<std::string>(SUMO_ATTR_STATE, nullptr, ok));
1413  const double foeVisibilityDistance = attrs.getOpt<double>(SUMO_ATTR_VISIBILITY_DISTANCE, nullptr, ok, state == LINKSTATE_ZIPPER ? 100 : 4.5);
1414  const bool keepClear = attrs.getOpt<bool>(SUMO_ATTR_KEEP_CLEAR, nullptr, ok, true);
1415  const bool indirect = attrs.getOpt<bool>(SUMO_ATTR_INDIRECT, nullptr, ok, false);
1416  std::string tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, nullptr, ok, "");
1417  std::string viaID = attrs.getOpt<std::string>(SUMO_ATTR_VIA, nullptr, ok, "");
1418 
1420  if (from == nullptr) {
1421  WRITE_ERRORF(TL("Unknown from-edge '%' in connection."), fromID);
1422  return;
1423  }
1424  myPreviousEdgeIdx = from->getNumericalID();
1425  MSEdge* to = MSEdge::dictionary(toID);
1426  if (to == nullptr) {
1427  WRITE_ERRORF(TL("Unknown to-edge '%' in connection."), toID);
1428  return;
1429  }
1430  if (fromLaneIdx < 0 || fromLaneIdx >= (int)from->getLanes().size() ||
1431  toLaneIdx < 0 || toLaneIdx >= (int)to->getLanes().size()) {
1432  WRITE_ERRORF(TL("Invalid lane index in connection from '%' to '%'."), from->getID(), to->getID());
1433  return;
1434  }
1435  MSLane* fromLane = from->getLanes()[fromLaneIdx];
1436  MSLane* toLane = to->getLanes()[toLaneIdx];
1437  assert(fromLane);
1438  assert(toLane);
1439 
1440  MSTrafficLightLogic* logic = nullptr;
1441  int tlLinkIdx = -1;
1442  if (tlID != "") {
1443  tlLinkIdx = attrs.get<int>(SUMO_ATTR_TLLINKINDEX, nullptr, ok);
1444  // make sure that the index is in range
1446  if ((tlLinkIdx < 0 || tlLinkIdx >= (int)logic->getCurrentPhaseDef().getState().size())
1447  && logic->getLogicType() != TrafficLightType::RAIL_SIGNAL
1448  && logic->getLogicType() != TrafficLightType::RAIL_CROSSING) {
1449  WRITE_ERROR("Invalid " + toString(SUMO_ATTR_TLLINKINDEX) + " '" + toString(tlLinkIdx) +
1450  "' in connection controlled by '" + tlID + "'");
1451  return;
1452  }
1453  if (!ok) {
1454  return;
1455  }
1456  }
1457  double length;
1458  // build the link
1459  MSLane* via = nullptr;
1460  if (viaID != "" && MSGlobals::gUsingInternalLanes) {
1461  via = MSLane::dictionary(viaID);
1462  if (via == nullptr) {
1463  WRITE_ERROR("An unknown lane ('" + viaID +
1464  "') should be set as a via-lane for lane '" + toLane->getID() + "'.");
1465  return;
1466  }
1467  length = via->getLength();
1468  } else if (toLane->getEdge().isCrossing()) {
1469  length = toLane->getLength();
1470  } else {
1471  length = fromLane->getShape()[-1].distanceTo(toLane->getShape()[0]);
1472  }
1473  myCurrentLink = new MSLink(fromLane, toLane, via, dir, state, length, foeVisibilityDistance, keepClear, logic, tlLinkIdx, indirect);
1474  if (via != nullptr) {
1475  via->addIncomingLane(fromLane, myCurrentLink);
1476  } else {
1477  toLane->addIncomingLane(fromLane, myCurrentLink);
1478  }
1479  toLane->addApproachingLane(fromLane, myNetworkVersion < MMVersion(0, 25));
1480 
1481  // if a traffic light is responsible for it, inform the traffic light
1482  // check whether this link is controlled by a traffic light
1483  // we can not reuse logic here because it might be an inactive one
1484  if (tlID != "") {
1485  myJunctionControlBuilder.getTLLogic(tlID).addLink(myCurrentLink, fromLane, tlLinkIdx);
1486  }
1487  // add the link
1488  fromLane->addLink(myCurrentLink);
1489 
1490  } catch (InvalidArgument& e) {
1491  WRITE_ERROR(e.what());
1492  }
1493 }
1494 
1495 
1496 void
1498  if (myCurrentLink == nullptr) {
1499  throw InvalidArgument(toString(SUMO_TAG_CONFLICT) + " must occur within a " + toString(SUMO_TAG_CONNECTION) + " element");
1500  }
1502  return;
1503  }
1504  bool ok = true;
1505  const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
1506  const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
1507  const int fromLaneIdx = attrs.get<int>(SUMO_ATTR_FROM_LANE, nullptr, ok);
1508  const int toLaneIdx = attrs.get<int>(SUMO_ATTR_TO_LANE, nullptr, ok);
1509  double startPos = attrs.get<double>(SUMO_ATTR_STARTPOS, nullptr, ok);
1510  double endPos = attrs.get<double>(SUMO_ATTR_ENDPOS, nullptr, ok);
1511  MSEdge* from = MSEdge::dictionary(fromID);
1512  if (from == nullptr) {
1513  WRITE_ERRORF(TL("Unknown from-edge '%' in conflict."), fromID);
1514  return;
1515  }
1516  MSEdge* to = MSEdge::dictionary(toID);
1517  if (to == nullptr) {
1518  WRITE_ERRORF(TL("Unknown to-edge '%' in connflict."), toID);
1519  return;
1520  }
1521  if (fromLaneIdx < 0 || fromLaneIdx >= (int)from->getLanes().size() ||
1522  toLaneIdx < 0 || toLaneIdx >= (int)to->getLanes().size()) {
1523  WRITE_ERRORF(TL("Invalid lane index in conflict with '%' to '%'."), from->getID(), to->getID());
1524  return;
1525  }
1526  MSLane* fromLane = from->getLanes()[fromLaneIdx];
1527  MSLane* toLane = to->getLanes()[toLaneIdx];
1528  assert(fromLane);
1529  assert(toLane);
1530  myCurrentLink->addCustomConflict(fromLane, toLane, startPos, endPos);
1531 }
1532 
1533 
1535 NLHandler::parseLinkDir(const std::string& dir) {
1536  if (SUMOXMLDefinitions::LinkDirections.hasString(dir)) {
1538  } else {
1539  throw InvalidArgument("Unrecognised link direction '" + dir + "'.");
1540  }
1541 }
1542 
1543 
1544 LinkState
1545 NLHandler::parseLinkState(const std::string& state) {
1546  if (SUMOXMLDefinitions::LinkStates.hasString(state)) {
1547  return SUMOXMLDefinitions::LinkStates.get(state);
1548  } else {
1549  if (state == "t") { // legacy networks
1550  // WRITE_WARNING(TL("Obsolete link state 't'. Use 'o' instead"));
1552  } else {
1553  throw InvalidArgument("Unrecognised link state '" + state + "'.");
1554  }
1555  }
1556 }
1557 
1558 
1559 // ----------------------------------
1560 void
1562  if (myNetIsLoaded) {
1563  //WRITE_WARNING(TL("POIs and Polygons should be loaded using option --po-files"))
1564  return;
1565  }
1566  bool ok = true;
1567  PositionVector s = attrs.get<PositionVector>(SUMO_ATTR_NET_OFFSET, nullptr, ok);
1568  Boundary convBoundary = attrs.get<Boundary>(SUMO_ATTR_CONV_BOUNDARY, nullptr, ok);
1569  Boundary origBoundary = attrs.get<Boundary>(SUMO_ATTR_ORIG_BOUNDARY, nullptr, ok);
1570  std::string proj = attrs.get<std::string>(SUMO_ATTR_ORIG_PROJ, nullptr, ok);
1571  if (ok) {
1572  Position networkOffset = s[0];
1573  GeoConvHelper::init(proj, networkOffset, origBoundary, convBoundary);
1574  if (OptionsCont::getOptions().getBool("fcd-output.geo") && !GeoConvHelper::getFinal().usingGeoProjection()) {
1575  WRITE_WARNING(TL("no valid geo projection loaded from network. fcd-output.geo will not work"));
1576  }
1577  }
1578 }
1579 
1580 
1581 void
1583  bool ok = true;
1584  myCurrentIsBroken = false;
1585  // get the id, report an error if not given or empty...
1586  myCurrentDistrictID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1587  if (!ok) {
1588  myCurrentIsBroken = true;
1589  return;
1590  }
1591  try {
1592  const std::string sinkID = myCurrentDistrictID + "-sink";
1593  const std::string sourceID = myCurrentDistrictID + "-source";
1594 
1595  MSEdge* sink = myEdgeControlBuilder.buildEdge(sinkID, SumoXMLEdgeFunc::CONNECTOR, "", "", -1, 0);
1596  if (!MSEdge::dictionary(sinkID, sink)) {
1597  delete sink;
1598  if (OptionsCont::getOptions().getBool("junction-taz")
1599  && myNet.getJunctionControl().get(myCurrentDistrictID) != nullptr) {
1600  // overwrite junction taz
1601  sink = MSEdge::dictionary(sinkID);
1603  WRITE_WARNINGF(TL("Replacing junction-taz '%' with loaded TAZ."), myCurrentDistrictID);
1604  } else {
1605  throw InvalidArgument("Another edge with the id '" + sinkID + "' exists.");
1606  }
1607  } else {
1608  sink->initialize(new std::vector<MSLane*>());
1609  }
1610  MSEdge* source = myEdgeControlBuilder.buildEdge(sourceID, SumoXMLEdgeFunc::CONNECTOR, "", "", -1, 0);
1611  if (!MSEdge::dictionary(sourceID, source)) {
1612  delete source;
1613  if (OptionsCont::getOptions().getBool("junction-taz")
1614  && myNet.getJunctionControl().get(myCurrentDistrictID) != nullptr) {
1615  // overwrite junction taz
1616  source = MSEdge::dictionary(sourceID);
1618  } else {
1619  throw InvalidArgument("Another edge with the id '" + sourceID + "' exists.");
1620  }
1621  } else {
1622  source->initialize(new std::vector<MSLane*>());
1623  }
1624  sink->setOtherTazConnector(source);
1625  source->setOtherTazConnector(sink);
1626  const std::vector<std::string>& desc = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_EDGES, myCurrentDistrictID.c_str(), ok);
1627  for (const std::string& eID : desc) {
1628  MSEdge* edge = MSEdge::dictionary(eID);
1629  // check whether the edge exists
1630  if (edge == nullptr) {
1631  throw InvalidArgument("The edge '" + eID + "' within district '" + myCurrentDistrictID + "' is not known.");
1632  }
1633  source->addSuccessor(edge);
1634  edge->addSuccessor(sink);
1635  }
1636  source->setParameter("taz", myCurrentDistrictID);
1637  sink->setParameter("taz", myCurrentDistrictID);
1638  RGBColor color = attrs.getOpt<RGBColor>(SUMO_ATTR_COLOR, myCurrentDistrictID.c_str(), ok, RGBColor::parseColor("1.0,.33,.33"));
1639  const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, myCurrentDistrictID.c_str(), ok, "");
1640  source->setParameter("tazColor", toString(color));
1641  sink->setParameter("tazColor", toString(color));
1642 
1643  if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
1645  const bool fill = attrs.getOpt<bool>(SUMO_ATTR_FILL, myCurrentDistrictID.c_str(), ok, false);
1646  if (shape.size() != 0) {
1647  if (!myNet.getShapeContainer().addPolygon(myCurrentDistrictID, "taz", color, 0, 0, "", false, shape, false, fill, 1.0, false, name)) {
1648  WRITE_WARNINGF(TL("Skipping visualization of taz '%', polygon already exists."), myCurrentDistrictID);
1649  } else {
1651  myCurrentIsBroken = false;
1652  }
1653  }
1654  }
1655  } catch (InvalidArgument& e) {
1656  WRITE_ERROR(e.what());
1657  myCurrentIsBroken = true;
1658  }
1659 }
1660 
1661 
1662 void
1663 NLHandler::addDistrictEdge(const SUMOSAXAttributes& attrs, bool isSource) {
1664  if (myCurrentIsBroken) {
1665  // earlier error
1666  return;
1667  }
1668  bool ok = true;
1669  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, myCurrentDistrictID.c_str(), ok);
1670  MSEdge* succ = MSEdge::dictionary(id);
1671  if (succ != nullptr) {
1672  // connect edge
1673  if (isSource) {
1674  MSEdge::dictionary(myCurrentDistrictID + "-source")->addSuccessor(succ);
1675  } else {
1676  succ->addSuccessor(MSEdge::dictionary(myCurrentDistrictID + "-sink"));
1677  }
1678  } else {
1679  WRITE_ERRORF(TL("At district '%': succeeding edge '%' does not exist."), myCurrentDistrictID, id);
1680  }
1681 }
1682 
1683 
1684 void
1686  bool ok = true;
1687  const std::vector<std::string>& edgeIDs = attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, nullptr, ok);
1688  if (ok) {
1689  for (const std::string& eID : edgeIDs) {
1690  MSEdge* edge = MSEdge::dictionary(eID);
1691  if (edge == nullptr) {
1692  WRITE_ERRORF(TL("Unknown edge '%' in roundabout"), eID);
1693  } else {
1694  edge->markAsRoundabout();
1695  }
1696  }
1697  }
1698 }
1699 
1700 
1701 void
1703  bool ok = true;
1704  MESegment::MesoEdgeType edgeType = myNet.getMesoType(""); // init defaults
1705  edgeType.tauff = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MESO_TAUFF, myCurrentTypeID.c_str(), ok, edgeType.tauff);
1706  edgeType.taufj = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MESO_TAUFJ, myCurrentTypeID.c_str(), ok, edgeType.taufj);
1707  edgeType.taujf = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MESO_TAUJF, myCurrentTypeID.c_str(), ok, edgeType.taujf);
1708  edgeType.taujj = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MESO_TAUJJ, myCurrentTypeID.c_str(), ok, edgeType.taujj);
1709  edgeType.jamThreshold = attrs.getOpt<double>(SUMO_ATTR_JAM_DIST_THRESHOLD, myCurrentTypeID.c_str(), ok, edgeType.jamThreshold);
1710  edgeType.junctionControl = attrs.getOpt<bool>(SUMO_ATTR_MESO_JUNCTION_CONTROL, myCurrentTypeID.c_str(), ok, edgeType.junctionControl);
1711  edgeType.tlsPenalty = attrs.getOpt<double>(SUMO_ATTR_MESO_TLS_PENALTY, myCurrentTypeID.c_str(), ok, edgeType.tlsPenalty);
1712  edgeType.tlsFlowPenalty = attrs.getOpt<double>(SUMO_ATTR_MESO_TLS_FLOW_PENALTY, myCurrentTypeID.c_str(), ok, edgeType.tlsFlowPenalty);
1714  edgeType.overtaking = attrs.getOpt<bool>(SUMO_ATTR_MESO_OVERTAKING, myCurrentTypeID.c_str(), ok, edgeType.overtaking);
1715 
1716  if (ok) {
1717  myNet.addMesoType(myCurrentTypeID, edgeType);
1718  }
1719  if (myNetIsLoaded) {
1720  myHaveSeenMesoEdgeType = true;
1721  }
1722 }
1723 
1724 // ----------------------------------
1725 void
1727  try {
1729  } catch (InvalidArgument& e) {
1730  WRITE_ERROR(e.what());
1731  }
1732 }
1733 
1734 
1735 void
1737  if (!myCurrentIsBroken) {
1738  try {
1740  } catch (InvalidArgument& e) {
1741  WRITE_ERROR(e.what());
1742  myCurrentIsBroken = true;
1743  }
1744  }
1745  myCurrentWAUTID = "";
1746 }
1747 
1748 
1749 Position
1750 NLShapeHandler::getLanePos(const std::string& poiID, const std::string& laneID, double lanePos, bool friendlyPos, double lanePosLat) {
1751  MSLane* lane = MSLane::dictionary(laneID);
1752  if (lane == nullptr) {
1753  WRITE_ERRORF(TL("Lane '%' to place poi '%' on is not known."), laneID, poiID);
1754  return Position::INVALID;
1755  }
1756  if (lanePos < 0) {
1757  lanePos = lane->getLength() + lanePos;
1758  }
1759  if ((lanePos < 0) && friendlyPos) {
1760  lanePos = 0;
1761  }
1762  if ((lanePos > lane->getLength()) && friendlyPos) {
1763  lanePos = lane->getLength();
1764  }
1765  if (lanePos < 0 || lanePos > lane->getLength()) {
1766  WRITE_WARNINGF(TL("lane position % for poi '%' is not valid."), toString(lanePos), poiID);
1767  }
1768  return lane->geometryPositionAtOffset(lanePos, -lanePosLat);
1769 }
1770 
1771 
1774  if (rs == nullptr) {
1775  throw InvalidArgument("Rail signal '" + toString((SumoXMLTag)element) + "' constraint must occur within a railSignalConstraints element");
1776  }
1777  bool ok = true;
1778  const std::string tripId = attrs.get<std::string>(SUMO_ATTR_TRIP_ID, nullptr, ok);
1779  const std::string signalID = attrs.get<std::string>(SUMO_ATTR_TLID, nullptr, ok);
1780  const std::string foesString = attrs.get<std::string>(SUMO_ATTR_FOES, nullptr, ok);
1781  const std::vector<std::string> foes = StringTokenizer(foesString).getVector();
1782  const int limit = attrs.getOpt<int>(SUMO_ATTR_LIMIT, nullptr, ok, (int)foes.size());
1783  const bool active = attrs.getOpt<bool>(SUMO_ATTR_ACTIVE, nullptr, ok, true);
1784 
1785  if (!MSNet::getInstance()->getTLSControl().knows(signalID)) {
1786  throw InvalidArgument("Rail signal '" + signalID + "' in railSignalConstraints is not known");
1787  }
1788  MSRailSignal* signal = dynamic_cast<MSRailSignal*>(MSNet::getInstance()->getTLSControl().get(signalID).getDefault());
1789  if (signal == nullptr) {
1790  throw InvalidArgument("Traffic light '" + signalID + "' is not a rail signal");
1791  }
1793  switch (element) {
1794  case SUMO_TAG_PREDECESSOR:
1795  type = MSRailSignalConstraint::ConstraintType::PREDECESSOR;
1796  break;
1798  type = MSRailSignalConstraint::ConstraintType::INSERTION_PREDECESSOR;
1799  break;
1801  type = MSRailSignalConstraint::ConstraintType::FOE_INSERTION;
1802  break;
1804  type = MSRailSignalConstraint::ConstraintType::INSERTION_ORDER;
1805  break;
1807  type = MSRailSignalConstraint::ConstraintType::BIDI_PREDECESSOR;
1808  break;
1809  default:
1810  throw InvalidArgument("Unsupported rail signal constraint '" + toString((SumoXMLTag)element) + "'");
1811  }
1812  Parameterised* result = nullptr;
1813  if (ok) {
1814  for (const std::string& foe : foes) {
1815  MSRailSignalConstraint* c = new MSRailSignalConstraint_Predecessor(type, signal, foe, limit, active);
1816  rs->addConstraint(tripId, c);
1817  // XXX if there are multiple foes, only one constraint will receive the parameters
1818  result = c;
1819  }
1820  }
1821  return result;
1822 }
1823 
1824 
1825 /****************************************************************************/
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:270
void setOtherTazConnector(const MSEdge *edge)
Definition: MSEdge.h:292
void setJunctions(MSJunction *from, MSJunction *to)
Definition: MSEdge.cpp:1255
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:1179
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:1009
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:177
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:983
void markAsRoundabout()
Definition: MSEdge.h:702
static bool gUseMesoSim
Definition: MSGlobals.h:103
static bool gLefthand
Whether lefthand-drive is being simulated.
Definition: MSGlobals.h:169
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:2760
void addIncomingLane(MSLane *lane, MSLink *viaLink)
Definition: MSLane.cpp:2750
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:2385
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:182
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:360
void addRestriction(const std::string &id, const SUMOVehicleClass svc, const double speed)
Adds a restriction for an edge type.
Definition: MSNet.cpp:345
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:365
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:723
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:1046
MSLink * myCurrentLink
the link element for the connection currently being parsed
Definition: NLHandler.h:382
void addRoundabout(const SUMOSAXAttributes &attrs)
Definition: NLHandler.cpp:1685
void addWAUTSwitch(const SUMOSAXAttributes &attrs)
Definition: NLHandler.cpp:683
virtual void addMesoEdgeType(const SUMOSAXAttributes &attrs)
Loads edge type specific meso parameters.
Definition: NLHandler.cpp:1702
bool myCurrentIsBroken
Definition: NLHandler.h:347
void addE3Entry(const SUMOSAXAttributes &attrs)
Adds an entry to the currently processed e3 detector.
Definition: NLHandler.cpp:1289
void beginEdgeParsing(const SUMOSAXAttributes &attrs)
begins the processing of an edge
Definition: NLHandler.cpp:416
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:803
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:896
static Parameterised * addPredecessorConstraint(int element, const SUMOSAXAttributes &attrs, MSRailSignal *rs)
Definition: NLHandler.cpp:1773
virtual void addVTypeProbeDetector(const SUMOSAXAttributes &attrs)
Builds a vtype-detector using the given specification.
Definition: NLHandler.cpp:1001
void addDistrictEdge(const SUMOSAXAttributes &attrs, bool isSource)
Definition: NLHandler.cpp:1663
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:618
void addFunction(const SUMOSAXAttributes &attrs)
adds a switching condition function to the traffic lights logic currently build
Definition: NLHandler.cpp:906
int myPreviousEdgeIdx
Definition: NLHandler.h:388
void addLane(const SUMOSAXAttributes &attrs)
adds a lane to the previously opened edge
Definition: NLHandler.cpp:510
void initJunctionLogic(const SUMOSAXAttributes &attrs)
begins the reading of a junction row logic
Definition: NLHandler.cpp:748
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:968
virtual void openJunction(const SUMOSAXAttributes &attrs)
opens a junction for processing
Definition: NLHandler.cpp:573
virtual void endE3Detector()
Builds of an e3 detector using collected values.
Definition: NLHandler.cpp:1726
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:1582
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:763
void closeWAUT()
Definition: NLHandler.cpp:1736
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:885
void setLocation(const SUMOSAXAttributes &attrs)
Parses network location description.
Definition: NLHandler.cpp:1561
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:655
LinkState parseLinkState(const std::string &state)
Parses the given character into an enumeration typed link state.
Definition: NLHandler.cpp:1545
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:1497
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:919
virtual ~NLHandler()
Destructor.
Definition: NLHandler.cpp:83
void addE3Exit(const SUMOSAXAttributes &attrs)
Adds an exit to the currently processed e3 detector.
Definition: NLHandler.cpp:1302
void beginE3Detector(const SUMOSAXAttributes &attrs)
Starts building of an e3 detector using the given specification.
Definition: NLHandler.cpp:1245
virtual void closeEdge()
Closes the process of building an edge.
Definition: NLHandler.cpp:492
void closeFunction()
adds a switching condition function to the traffic lights logic currently build
Definition: NLHandler.cpp:914
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:1535
bool myNetIsLoaded
whether the location element was already loadee
Definition: NLHandler.h:376
void addWAUTJunction(const SUMOSAXAttributes &attrs)
Definition: NLHandler.cpp:702
virtual void addRouteProbeDetector(const SUMOSAXAttributes &attrs)
Builds a routeProbe-detector using the given specification.
Definition: NLHandler.cpp:1022
virtual void addEdgeLaneMeanData(const SUMOSAXAttributes &attrs, int objecttype)
Builds edge or lane base mean data collector using the given specification.
Definition: NLHandler.cpp:1315
bool myHaveWarnedAboutInvalidTLType
Definition: NLHandler.h:349
void addParam(const SUMOSAXAttributes &attrs)
Definition: NLHandler.cpp:638
void addConnection(const SUMOSAXAttributes &attrs)
adds a connection
Definition: NLHandler.cpp:1394
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:1750
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 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:317
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