Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
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-2026 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"
31#include "NLDetectorBuilder.h"
32#include "NLTriggerBuilder.h"
41#include <microsim/MSGlobals.h>
42#include <microsim/MSLane.h>
43#include <microsim/MSJunction.h>
50#include <mesosim/MESegment.h>
55#include <utils/shapes/Shape.h>
56
57
58// ===========================================================================
59// method definitions
60// ===========================================================================
61NLHandler::NLHandler(const std::string& file, MSNet& net,
62 NLDetectorBuilder& detBuilder,
63 NLTriggerBuilder& triggerBuilder,
64 NLEdgeControlBuilder& edgeBuilder,
65 NLJunctionControlBuilder& junctionBuilder) :
66 MSRouteHandler(file, true),
67 myNet(net), myActionBuilder(net),
68 myCurrentIsInternalToSkip(false),
69 myDetectorBuilder(detBuilder), myTriggerBuilder(triggerBuilder),
70 myEdgeControlBuilder(edgeBuilder), myJunctionControlBuilder(junctionBuilder),
71 myAmParsingTLLogicOrJunction(false), myCurrentIsBroken(false),
72 myHaveWarnedAboutInvalidTLType(false),
73 myHaveSeenInternalEdge(false),
74 myHaveJunctionHigherSpeeds(false),
75 myHaveSeenDefaultLength(false),
76 myHaveSeenNeighs(false),
77 myHaveSeenAdditionalSpeedRestrictions(false),
78 myHaveSeenTLSParams(false),
79 myNetworkVersion(0, 0),
80 myNetIsLoaded(false) {
81}
82
83
85
86
87void
89 const SUMOSAXAttributes& attrs) {
90 try {
91 switch (element) {
92 case SUMO_TAG_NET: {
93 bool ok;
94 MSGlobals::gLefthand = attrs.getOpt<bool>(SUMO_ATTR_LEFTHAND, nullptr, ok, false);
95 myHaveJunctionHigherSpeeds = attrs.getOpt<bool>(SUMO_ATTR_HIGHER_SPEED, nullptr, ok, false);
96 myNetworkVersion = StringUtils::toVersion(attrs.get<std::string>(SUMO_ATTR_VERSION, nullptr, ok, false));
97 break;
98 }
99 case SUMO_TAG_EDGE:
100 beginEdgeParsing(attrs);
101 break;
102 case SUMO_TAG_LANE:
103 addLane(attrs);
104 break;
105 case SUMO_TAG_NEIGH:
108 }
109 myHaveSeenNeighs = true;
110 break;
112 openJunction(attrs);
113 initJunctionLogic(attrs);
114 break;
115 case SUMO_TAG_PHASE:
116 addPhase(attrs);
117 break;
119 addCondition(attrs);
120 break;
122 addAssignment(attrs);
123 break;
125 addFunction(attrs);
126 break;
128 addConnection(attrs);
129 break;
131 addConflict(attrs);
132 break;
133 case SUMO_TAG_TLLOGIC:
135 break;
136 case SUMO_TAG_REQUEST:
137 addRequest(attrs);
138 break;
139 case SUMO_TAG_WAUT:
140 openWAUT(attrs);
141 break;
143 addWAUTSwitch(attrs);
144 break;
146 addWAUTJunction(attrs);
147 break;
150 addE1Detector(attrs);
151 break;
154 addE2Detector(attrs);
155 break;
158 beginE3Detector(attrs);
159 break;
161 addE3Entry(attrs);
162 break;
164 addE3Exit(attrs);
165 break;
168 break;
169 case SUMO_TAG_VSS:
171 break;
174 break;
177 break;
183 break;
186 break;
190 break;
191 case SUMO_TAG_ACCESS:
193 break;
197 break;
200 break;
203 break;
206 break;
209 break;
212 break;
215 break;
218 break;
221 break;
224 break;
227 break;
229 setLocation(attrs);
230 break;
231 case SUMO_TAG_TAZ:
232 addDistrict(attrs);
233 break;
235 addDistrictEdge(attrs, true);
236 break;
237 case SUMO_TAG_TAZSINK:
238 addDistrictEdge(attrs, false);
239 break;
241 addRoundabout(attrs);
242 break;
243 case SUMO_TAG_TYPE: {
244 bool ok = true;
245 myCurrentTypeID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
246 break;
247 }
249 bool ok = true;
250 const SUMOVehicleClass svc = getVehicleClassID(attrs.get<std::string>(SUMO_ATTR_VCLASS, myCurrentTypeID.c_str(), ok));
251 const double speed = attrs.get<double>(SUMO_ATTR_SPEED, myCurrentTypeID.c_str(), ok);
252 if (ok) {
254 }
255 if (myNetIsLoaded) {
257 }
258 break;
259 }
260 case SUMO_TAG_PREFERENCE: {
261 bool ok = true;
262 const std::string routingType = attrs.get<std::string>(SUMO_ATTR_ROUTINGTYPE, nullptr, ok);
263 const double prio = attrs.get<double>(SUMO_ATTR_PRIORITY, routingType.c_str(), ok);
264 if (prio <= 0) {
265 throw InvalidArgument("In preference for routingType '" + routingType + "', priority must be positve");
266 }
267 if (attrs.hasAttribute(SUMO_ATTR_VCLASSES)) {
268 StringTokenizer st(attrs.get<std::string>(SUMO_ATTR_VCLASSES, routingType.c_str(), ok));
269 for (std::string className : st.getVector()) {
270 myNet.addPreference(routingType, getVehicleClassID(className), prio);
271 }
272 } else if (!attrs.hasAttribute(SUMO_ATTR_VTYPES)) {
273 // general preferenze applying to all types and vClasses
274 myNet.addPreference(routingType, "", prio);
275 }
276 if (attrs.hasAttribute(SUMO_ATTR_VTYPES)) {
277 StringTokenizer st(attrs.get<std::string>(SUMO_ATTR_VTYPES, routingType.c_str(), ok));
278 for (std::string typeName : st.getVector()) {
279 myNet.addPreference(routingType, typeName, prio);
280 }
281 }
282 break;
283 }
284 case SUMO_TAG_STOPOFFSET: {
285 bool ok = true;
286 const StopOffset stopOffset(attrs, ok);
287 if (!ok) {
289 } else {
291 }
292 break;
293 }
295 bool ok = true;
296 const std::string signalID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
297 if (!MSNet::getInstance()->getTLSControl().knows(signalID)) {
298 throw InvalidArgument("Rail signal '" + signalID + "' in railSignalConstraints is not known");
299 }
301 if (myConstrainedSignal == nullptr) {
302 throw InvalidArgument("Traffic light '" + signalID + "' is not a rail signal");
303 }
304 break;
305 }
306 case SUMO_TAG_PREDECESSOR: // intended fall-through
307 case SUMO_TAG_FOE_INSERTION: // intended fall-through
308 case SUMO_TAG_INSERTION_PREDECESSOR: // intended fall-through
309 case SUMO_TAG_INSERTION_ORDER: // intended fall-through
312 break;
314 addDeadlock(attrs);
315 break;
317 addDeadlockRoute(attrs);
318 break;
319 default:
320 break;
321 }
322 } catch (InvalidArgument& e) {
323 myCurrentIsBroken = true;
324 WRITE_ERROR(e.what());
325 }
326 MSRouteHandler::myStartElement(element, attrs);
327 if (element == SUMO_TAG_PARAM && !myCurrentIsBroken) {
328 addParam(attrs);
329 }
330}
331
332
333void
335 switch (element) {
336 case SUMO_TAG_EDGE:
337 closeEdge();
338 break;
339 case SUMO_TAG_LANE:
342 myLastParameterised.pop_back();
343 }
344 break;
346 if (!myCurrentIsBroken) {
347 try {
349 } catch (InvalidArgument& e) {
350 WRITE_ERROR(e.what());
351 }
352 }
354 break;
355 case SUMO_TAG_TLLOGIC:
356 if (!myCurrentIsBroken) {
357 try {
359 } catch (InvalidArgument& e) {
361 delete phase;
362 }
363 WRITE_ERROR(e.what());
364 }
365 }
367 break;
370 break;
371 case SUMO_TAG_WAUT:
372 closeWAUT();
373 break;
375 myConstrainedSignal = nullptr;
376 break;
382 if (!myCurrentIsBroken) {
383 myLastParameterised.pop_back();
384 }
385 break;
389 if (!myCurrentIsBroken) {
390 myLastParameterised.pop_back();
391 }
392 break;
396 myLastParameterised.pop_back();
397 break;
403 myLastParameterised.pop_back();
404 break;
405 case SUMO_TAG_PREDECESSOR: // intended fall-through
406 case SUMO_TAG_FOE_INSERTION: // intended fall-through
407 case SUMO_TAG_INSERTION_PREDECESSOR: // intended fall-through
408 case SUMO_TAG_INSERTION_ORDER: // intended fall-through
410 myLastParameterised.pop_back();
411 break;
412 case SUMO_TAG_NET:
413 // build junction graph
414 for (JunctionGraph::iterator it = myJunctionGraph.begin(); it != myJunctionGraph.end(); ++it) {
415 MSEdge* edge = MSEdge::dictionary(it->first);
416 MSJunction* from = myJunctionControlBuilder.retrieve(it->second.first);
417 MSJunction* to = myJunctionControlBuilder.retrieve(it->second.second);
418 if (from == nullptr) {
419 WRITE_ERRORF(TL("Unknown from-node '%' for edge '%'."), it->second.first, it->first);
420 return;
421 }
422 if (to == nullptr) {
423 WRITE_ERRORF(TL("Unknown to-node '%' for edge '%'."), it->second.second, it->first);
424 return;
425 }
426 if (edge != nullptr) {
427 edge->setJunctions(from, to);
428 from->addOutgoing(edge);
429 to->addIncoming(edge);
430 }
431 }
432 myNetIsLoaded = true;
433 break;
434 default:
435 break;
436 }
438}
439
440
441
442// ---- the root/edge - element
443void
445 bool ok = true;
446 myCurrentIsBroken = false;
447 // get the id, report an error if not given or empty...
448 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
449 if (!ok) {
450 myCurrentIsBroken = true;
451 return;
452 }
453 // parse the function
455 if (!ok) {
456 myCurrentIsBroken = true;
457 return;
458 }
459 // omit internal edges if not wished
460 if (id[0] == ':') {
464 return;
465 }
466 std::string junctionID = SUMOXMLDefinitions::getJunctionIDFromInternalEdge(id);
467 myJunctionGraph[id] = std::make_pair(junctionID, junctionID);
468 } else {
470 myJunctionGraph[id] = std::make_pair(
471 attrs.get<std::string>(SUMO_ATTR_FROM, id.c_str(), ok),
472 attrs.get<std::string>(SUMO_ATTR_TO, id.c_str(), ok));
473 }
474 if (!ok) {
475 myCurrentIsBroken = true;
476 return;
477 }
479 // get the street name
480 const std::string streetName = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
481 // get the edge type
482 const std::string edgeType = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
483 const std::string routingType = attrs.getOpt<std::string>(SUMO_ATTR_ROUTINGTYPE, id.c_str(), ok, "");
484 // get the edge priority (only for visualization)
485 const int priority = attrs.getOpt<int>(SUMO_ATTR_PRIORITY, id.c_str(), ok, -1); // default taken from netbuild/NBFrame option 'default.priority'
486 // get the bidi-edge
487 const std::string bidi = attrs.getOpt<std::string>(SUMO_ATTR_BIDI, id.c_str(), ok, "");
488 // get the kilometrage/mileage (for visualization and output)
489 const double distance = attrs.getOpt<double>(SUMO_ATTR_DISTANCE, id.c_str(), ok, 0);
490
491 if (!ok) {
492 myCurrentIsBroken = true;
493 return;
494 }
495 //
496 try {
497 myEdgeControlBuilder.beginEdgeParsing(id, func, streetName, edgeType, routingType, priority, bidi, distance);
498 } catch (InvalidArgument& e) {
499 WRITE_ERROR(e.what());
500 myCurrentIsBroken = true;
501 }
502
503 if (func == SumoXMLEdgeFunc::CROSSING) {
504 //get the crossingEdges attribute (to implement the other side of the road pushbutton)
505 const std::string crossingEdges = attrs.getOpt<std::string>(SUMO_ATTR_CROSSING_EDGES, id.c_str(), ok, "");
506 if (!crossingEdges.empty()) {
507 std::vector<std::string> crossingEdgesVector;
508 StringTokenizer edges(crossingEdges);
509 while (edges.hasNext()) {
510 crossingEdgesVector.push_back(edges.next());
511 }
512 myEdgeControlBuilder.addCrossingEdges(crossingEdgesVector);
513 }
514 }
517}
518
519
520void
522 myLastParameterised.clear();
523 // omit internal edges if not wished and broken edges
525 return;
526 }
527 try {
529 MSEdge::dictionary(e->getID(), e);
531 } catch (InvalidArgument& e) {
532 WRITE_ERROR(e.what());
533 }
534}
535
536
537// ---- the root/edge/lanes/lane - element
538void
540 // omit internal edges if not wished and broken edges
542 return;
543 }
544 bool ok = true;
545 // get the id, report an error if not given or empty...
546 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
547 if (!ok) {
548 myCurrentIsBroken = true;
549 return;
550 }
551 const double maxSpeed = attrs.get<double>(SUMO_ATTR_SPEED, id.c_str(), ok);
552 const double friction = attrs.getOpt<double>(SUMO_ATTR_FRICTION, id.c_str(), ok, (double)(1.), false);
553 const double length = attrs.get<double>(SUMO_ATTR_LENGTH, id.c_str(), ok);
554 // sanity check values that could lead to crashing later on
555 if (std::isnan(length)) {
556 WRITE_ERRORF(TL("Attribute length of lane '%' is invalid (%)"), id, length);
557 myCurrentIsBroken = true;
558 return;
559 }
560 if (std::isnan(maxSpeed)) {
561 WRITE_ERRORF(TL("Attribute maxSpeed of lane '%' is invalid (%)"), id, maxSpeed);
562 myCurrentIsBroken = true;
563 return;
564 }
565 const std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, id.c_str(), ok, "", false);
566 const std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
567 const std::string changeLeftS = attrs.getOpt<std::string>(SUMO_ATTR_CHANGE_LEFT, id.c_str(), ok, "");
568 const std::string changeRightS = attrs.getOpt<std::string>(SUMO_ATTR_CHANGE_RIGHT, id.c_str(), ok, "");
569 const double width = attrs.getOpt<double>(SUMO_ATTR_WIDTH, id.c_str(), ok, SUMO_const_laneWidth);
570 const PositionVector shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok);
571 const PositionVector outlineShape = attrs.getOpt<PositionVector>(SUMO_ATTR_OUTLINESHAPE, id.c_str(), ok, PositionVector());
572 const int index = attrs.get<int>(SUMO_ATTR_INDEX, id.c_str(), ok);
573 const bool isRampAccel = attrs.getOpt<bool>(SUMO_ATTR_ACCELERATION, id.c_str(), ok, false);
574 const std::string type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
576 WRITE_ERRORF(TL("Shape of lane '%' is broken.\n Can not build according edge."), id);
577 myCurrentIsBroken = true;
578 return;
579 }
580 const SVCPermissions permissions = parseVehicleClasses(allow, disallow, myNetworkVersion);
581 SVCPermissions changeLeft = parseVehicleClasses(changeLeftS, "", myNetworkVersion);
582 SVCPermissions changeRight = parseVehicleClasses(changeRightS, "", myNetworkVersion);
584 // internally, changeLeft always checks for the higher lane index
585 // even though the higher lane index is to the right in a left-hand network
586 std::swap(changeLeft, changeRight);
587 }
588 if (permissions != SVCAll || changeLeft != SVCAll || changeRight != SVCAll) {
590 }
591 myCurrentIsBroken |= !ok;
592 if (!myCurrentIsBroken) {
593 try {
594 MSLane* lane = myEdgeControlBuilder.addLane(id, maxSpeed, friction, length, shape, width, permissions, changeLeft, changeRight, index, isRampAccel, type, outlineShape);
595 // insert the lane into the lane-dictionary, checking
596 if (!MSLane::dictionary(id, lane)) {
597 delete lane;
598 WRITE_ERRORF(TL("Another lane with the id '%' exists."), id);
599 myCurrentIsBroken = true;
600 myLastParameterised.push_back(nullptr);
601 } else {
602 myLastParameterised.push_back(lane);
603 }
604 } catch (InvalidArgument& e) {
605 WRITE_ERROR(e.what());
606 }
607 }
608}
609
610
611// ---- the root/junction - element
612void
614 myCurrentIsBroken = false;
615 bool ok = true;
616 // get the id, report an error if not given or empty...
617 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
618 if (!ok) {
619 myCurrentIsBroken = true;
620 return;
621 }
622 PositionVector shape;
623 if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
624 // inner junctions have no shape
625 shape = attrs.getOpt<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok, PositionVector());
626 if (shape.size() > 2) {
627 shape.closePolygon();
628 }
629 }
630 double x = attrs.get<double>(SUMO_ATTR_X, id.c_str(), ok);
631 double y = attrs.get<double>(SUMO_ATTR_Y, id.c_str(), ok);
632 double z = attrs.getOpt<double>(SUMO_ATTR_Z, id.c_str(), ok, 0);
633 const SumoXMLNodeType type = attrs.get<SumoXMLNodeType>(SUMO_ATTR_TYPE, id.c_str(), ok);
634 std::string key = attrs.getOpt<std::string>(SUMO_ATTR_KEY, id.c_str(), ok, "");
635 std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
636 // incoming lanes
637 std::vector<MSLane*> incomingLanes;
638 parseLanes(id, attrs.getStringSecure(SUMO_ATTR_INCLANES, ""), incomingLanes, ok);
639 // internal lanes
640 std::vector<MSLane*> internalLanes;
642 parseLanes(id, attrs.getStringSecure(SUMO_ATTR_INTLANES, ""), internalLanes, ok);
643 }
644 if (!ok) {
645 myCurrentIsBroken = true;
646 } else {
647 try {
648 myJunctionControlBuilder.openJunction(id, key, type, Position(x, y, z), shape, incomingLanes, internalLanes, name);
649 } catch (InvalidArgument& e) {
650 WRITE_ERROR(e.what() + std::string("\n Can not build according junction."));
651 myCurrentIsBroken = true;
652 }
653 }
654}
655
656
657void
658NLHandler::parseLanes(const std::string& junctionID,
659 const std::string& def, std::vector<MSLane*>& into, bool& ok) {
660 StringTokenizer st(def, " ");
661 while (ok && st.hasNext()) {
662 std::string laneID = st.next();
663 MSLane* lane = MSLane::dictionary(laneID);
664 if (!MSGlobals::gUsingInternalLanes && laneID[0] == ':') {
665 continue;
666 }
667 if (lane == nullptr) {
668 WRITE_ERRORF(TL("An unknown lane ('%') was tried to be set as incoming to junction '%'."), laneID, junctionID);
669 ok = false;
670 continue;
671 }
672 into.push_back(lane);
673 }
674}
675// ----
676
677void
679 bool ok = true;
680 const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
681 // circumventing empty string test
682 const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
683 if (myLastParameterised.size() > 0 && myLastParameterised.back() != nullptr) {
684 myLastParameterised.back()->setParameter(key, val);
685 }
686 // set
688 assert(key != "");
690 if (myNetIsLoaded) {
691 myHaveSeenTLSParams = true;
692 }
693 }
694}
695
696
697void
699 myCurrentIsBroken = false;
700 bool ok = true;
701 // get the id, report an error if not given or empty...
702 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
703 if (!ok) {
704 myCurrentIsBroken = true;
705 return;
706 }
707 SUMOTime refTime = attrs.getOptSUMOTimeReporting(SUMO_ATTR_REF_TIME, id.c_str(), ok, 0);
708 SUMOTime period = attrs.getOptSUMOTimeReporting(SUMO_ATTR_PERIOD, id.c_str(), ok, 0);
709 std::string startProg = attrs.get<std::string>(SUMO_ATTR_START_PROG, id.c_str(), ok);
710 if (!ok) {
711 myCurrentIsBroken = true;
712 }
713 if (!myCurrentIsBroken) {
714 myCurrentWAUTID = id;
715 try {
716 myJunctionControlBuilder.getTLLogicControlToUse().addWAUT(refTime, id, startProg, period);
717 } catch (InvalidArgument& e) {
718 WRITE_ERROR(e.what());
719 myCurrentIsBroken = true;
720 }
721 }
722}
723
724
725void
727 bool ok = true;
729 std::string to = attrs.get<std::string>(SUMO_ATTR_TO, myCurrentWAUTID.c_str(), ok);
730 if (!ok) {
731 myCurrentIsBroken = true;
732 }
733 if (!myCurrentIsBroken) {
734 try {
736 } catch (InvalidArgument& e) {
737 WRITE_ERROR(e.what());
738 myCurrentIsBroken = true;
739 }
740 }
741}
742
743
744void
746 bool ok = true;
747 std::string wautID = attrs.get<std::string>(SUMO_ATTR_WAUT_ID, nullptr, ok);
748 std::string junctionID = attrs.get<std::string>(SUMO_ATTR_JUNCTION_ID, nullptr, ok);
749 std::string procedure = attrs.getOpt<std::string>(SUMO_ATTR_PROCEDURE, nullptr, ok, "");
750 bool synchron = attrs.getOpt<bool>(SUMO_ATTR_SYNCHRON, nullptr, ok, false);
751 if (!ok) {
752 myCurrentIsBroken = true;
753 }
754 try {
755 if (!myCurrentIsBroken) {
756 myJunctionControlBuilder.getTLLogicControlToUse().addWAUTJunction(wautID, junctionID, procedure, synchron);
757 }
758 } catch (InvalidArgument& e) {
759 WRITE_ERROR(e.what());
760 myCurrentIsBroken = true;
761 }
762}
763
764
765void
767 if (myCurrentIsBroken) {
768 return;
769 }
770 bool ok = true;
771 int request = attrs.get<int>(SUMO_ATTR_INDEX, nullptr, ok);
772 bool cont = false;
773 cont = attrs.getOpt<bool>(SUMO_ATTR_CONT, nullptr, ok, false);
774 std::string response = attrs.get<std::string>(SUMO_ATTR_RESPONSE, nullptr, ok);
775 std::string foes = attrs.get<std::string>(SUMO_ATTR_FOES, nullptr, ok);
776 if (!ok) {
777 return;
778 }
779 // store received information
780 if (request >= 0 && response.length() > 0) {
781 try {
782 myJunctionControlBuilder.addLogicItem(request, response, foes, cont);
783 } catch (InvalidArgument& e) {
784 WRITE_ERROR(e.what());
785 }
786 }
787}
788
789
790void
792 if (myCurrentIsBroken) {
793 return;
794 }
796 bool ok = true;
797 // we either a have a junction or a legacy network with ROWLogic
798 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
799 if (ok) {
801 }
802}
803
804
805void
807 myCurrentIsBroken = false;
809 bool ok = true;
810 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
811 std::string programID = attrs.getOpt<std::string>(SUMO_ATTR_PROGRAMID, id.c_str(), ok, "<unknown>");
813 std::string typeS;
814 if (myJunctionControlBuilder.getTLLogicControlToUse().get(id, programID) == nullptr) {
815 // SUMO_ATTR_TYPE is not needed when only modifying the offset of an
816 // existing program
817 typeS = attrs.get<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok);
818 if (!ok) {
819 myCurrentIsBroken = true;
820 return;
821 }
822 if (SUMOXMLDefinitions::TrafficLightTypes.hasString(typeS)) {
824 } else {
825 WRITE_ERRORF(TL("Traffic light '%' has unknown type '%'."), id, typeS);
826 }
831 && type != TrafficLightType::OFF) {
833 WRITE_WARNINGF(TL("Traffic light type '%' cannot be used in mesoscopic simulation. Using '%' as fallback."), toString(type), toString(TrafficLightType::STATIC));
835 }
837 }
838 }
839 SUMOTime offset = attrs.getOptOffsetReporting(SUMO_ATTR_OFFSET, id.c_str(), ok, 0);
840 if (offset == SUMOTime_MAX) {
841 offset = string2time(OptionsCont::getOptions().getString("begin"));
842 }
843 if (!ok) {
844 myCurrentIsBroken = true;
845 return;
846 }
847 myJunctionControlBuilder.initTrafficLightLogic(id, programID, type, offset);
848}
849
850
851void
853 // try to get the phase definition
854 bool ok = true;
855 const std::string& id = myJunctionControlBuilder.getActiveKey();
857
859 const std::string state = attrs.get<std::string>(SUMO_ATTR_STATE, nullptr, ok);
860 if (duration == 0) {
861 WRITE_ERROR("Duration of phase " + toString(myJunctionControlBuilder.getLoadedPhases().size())
862 + " for tlLogic '" + myJunctionControlBuilder.getActiveKey()
863 + "' program '" + myJunctionControlBuilder.getActiveSubKey() + "' is zero.");
864 return;
865 }
866 if (!ok) {
867 return;
868 }
869 MSPhaseDefinition* phase = new MSPhaseDefinition(duration, state);
870
871 // if the traffic light is an actuated traffic light, try to get
872 // the minimum and maximum durations
873 phase->minDuration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MINDURATION, id.c_str(), ok, duration);
874 // if minDur is set but not maxDur, assume high maxDur (avoid using the absolute max in case we do some arithmetic later)
875 SUMOTime defaultMaxDur = attrs.hasAttribute(SUMO_ATTR_MINDURATION) ? std::numeric_limits<int>::max() : duration;
876 phase->maxDuration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MAXDURATION, id.c_str(), ok, defaultMaxDur);
877 phase->earliestEnd = attrs.getOptSUMOTimeReporting(SUMO_ATTR_EARLIEST_END, id.c_str(), ok, tDefault);
878 phase->latestEnd = attrs.getOptSUMOTimeReporting(SUMO_ATTR_LATEST_END, id.c_str(), ok, tDefault);
879 phase->nextPhases = attrs.getOpt<std::vector<int> >(SUMO_ATTR_NEXT, id.c_str(), ok);
880 phase->earlyTarget = attrs.getOpt<std::string>(SUMO_ATTR_EARLY_TARGET, id.c_str(), ok);
881 phase->finalTarget = attrs.getOpt<std::string>(SUMO_ATTR_FINAL_TARGET, id.c_str(), ok);
882 phase->name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok);
883
884 phase->vehext = attrs.getOptSUMOTimeReporting(SUMO_ATTR_VEHICLEEXTENSION, id.c_str(), ok, tDefault);
885 phase->yellow = attrs.getOptSUMOTimeReporting(SUMO_ATTR_YELLOW, id.c_str(), ok, tDefault);
886 phase->red = attrs.getOptSUMOTimeReporting(SUMO_ATTR_RED, id.c_str(), ok, tDefault);
887
888 if (attrs.hasAttribute(SUMO_ATTR_TYPE)) {
889 //SOTL attributes
890 //If the type attribute is not present, the parsed phase is of type "undefined" (MSPhaseDefinition constructor),
891 //in this way SOTL traffic light logic can recognize the phase as unsuitable or decides other
892 //behaviors. See SOTL traffic light logic implementations.
893 std::string phaseTypeString;
894 try {
895 phaseTypeString = attrs.get<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, false);
896 } catch (EmptyData&) {
897 MsgHandler::getWarningInstance()->inform("Empty type definition. Assuming phase type as SUMOSOTL_TagAttrDefinitions::SOTL_ATTL_TYPE_TRANSIENT");
898 phase->myTransientNotDecisional = false;
899 }
900 if (phaseTypeString.find("decisional") != std::string::npos) {
901 phase->myTransientNotDecisional = false;
902 } else if (phaseTypeString.find("transient") != std::string::npos) {
903 phase->myTransientNotDecisional = true;
904 } else {
905 MsgHandler::getWarningInstance()->inform("SOTL_ATTL_TYPE_DECISIONAL nor SOTL_ATTL_TYPE_TRANSIENT. Assuming phase type as SUMOSOTL_TagAttrDefinitions::SOTL_ATTL_TYPE_TRANSIENT");
906 phase->myTransientNotDecisional = false;
907 }
908 phase->myCommit = (phaseTypeString.find("commit") != std::string::npos);
909
910 if (phaseTypeString.find("target") != std::string::npos) {
911 std::string delimiter(" ,;");
912 //Phase declared as target, getting targetLanes attribute
913 try {
915 } catch (EmptyData&) {
916 MsgHandler::getErrorInstance()->inform("Missing targetLane definition for the target phase.");
917 delete phase;
918 return;
919 }
920 }
921 }
922
923 if (phase->maxDuration < phase->minDuration) {
924 WRITE_WARNINGF(TL("maxDur % should not be smaller than minDir % in phase of tlLogic %"), phase->maxDuration, phase->minDuration, id);
925 phase->maxDuration = phase->duration;
926 }
927
928 phase->myLastSwitch = string2time(OptionsCont::getOptions().getString("begin")) - 1; // SUMOTime-option
930}
931
932
933void
935 bool ok = true;
936 const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
937 const std::string value = attrs.get<std::string>(SUMO_ATTR_VALUE, id.c_str(), ok);
938 if (!myJunctionControlBuilder.addCondition(id, value)) {
939 WRITE_ERRORF(TL("Duplicate condition '%' in tlLogic '%'"), id, myJunctionControlBuilder.getActiveKey());
940 }
941}
942
943
944void
946 bool ok = true;
947 const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
948 const std::string check = attrs.get<std::string>(SUMO_ATTR_CHECK, nullptr, ok);
949 const std::string value = attrs.get<std::string>(SUMO_ATTR_VALUE, id.c_str(), ok);
950 myJunctionControlBuilder.addAssignment(id, check, value);
951}
952
953
954void
956 bool ok = true;
957 const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
958 const int nArgs = attrs.get<int>(SUMO_ATTR_NARGS, nullptr, ok);
960}
961
962void
966
967void
969 myCurrentIsBroken = false;
970 bool ok = true;
971 // get the id, report an error if not given or empty...
972 const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
973 if (!ok) {
974 myCurrentIsBroken = true;
975 return;
976 }
977 const SUMOTime period = attrs.getOptPeriod(id.c_str(), ok, SUMOTime_MAX_PERIOD);
978 const double position = attrs.get<double>(SUMO_ATTR_POSITION, id.c_str(), ok);
979 const double length = attrs.getOpt<double>(SUMO_ATTR_LENGTH, id.c_str(), ok, 0);
980 const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
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 const bool mesoTLS = attrs.getOpt<bool>(SUMO_ATTR_MESO_TLS, id.c_str(), ok, false);
985 const std::string lane = attrs.get<std::string>(SUMO_ATTR_LANE, id.c_str(), ok);
986 const std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
987 const std::string detectPersonsString = attrs.getOpt<std::string>(SUMO_ATTR_DETECT_PERSONS, id.c_str(), ok, "");
988 const int detectPersons = parseDetectPersons(detectPersonsString, id, ok);
989 if (!ok) {
990 myCurrentIsBroken = true;
991 return;
992 }
993 try {
994 Parameterised* det = myDetectorBuilder.buildInductLoop(id, lane, position, length, period,
996 friendlyPos, name, vTypes, nextEdges, mesoTLS, detectPersons);
997 myLastParameterised.push_back(det);
998 } catch (InvalidArgument& e) {
999 myCurrentIsBroken = true;
1000 WRITE_ERROR(e.what());
1001 } catch (IOError& e) {
1002 myCurrentIsBroken = true;
1003 WRITE_ERROR(e.what());
1004 }
1005}
1006
1007
1008void
1010 myCurrentIsBroken = false;
1011 bool ok = true;
1012 // get the id, report an error if not given or empty...
1013 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1014 if (!ok) {
1015 myCurrentIsBroken = true;
1016 return;
1017 }
1018 const double position = attrs.get<double>(SUMO_ATTR_POSITION, id.c_str(), ok);
1019 const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
1020 const std::string lane = attrs.get<std::string>(SUMO_ATTR_LANE, id.c_str(), ok);
1021 const std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1022 const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
1023 const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
1024 const std::string nextEdges = attrs.getOpt<std::string>(SUMO_ATTR_NEXT_EDGES, id.c_str(), ok, "");
1025 const std::string detectPersonsString = attrs.getOpt<std::string>(SUMO_ATTR_DETECT_PERSONS, id.c_str(), ok, "");
1026 const int detectPersons = parseDetectPersons(detectPersonsString, id, ok);
1027 if (!ok) {
1028 myCurrentIsBroken = true;
1029 return;
1030 }
1031 try {
1032 Parameterised* det = myDetectorBuilder.buildInstantInductLoop(id, lane, position, FileHelpers::checkForRelativity(file, getFileName()), friendlyPos, name, vTypes, nextEdges, detectPersons);
1033 myLastParameterised.push_back(det);
1034 } catch (InvalidArgument& e) {
1035 WRITE_ERROR(e.what());
1036 } catch (IOError& e) {
1037 WRITE_ERROR(e.what());
1038 }
1039 myCurrentIsBroken = true;
1040}
1041
1042
1043void
1045 WRITE_WARNING(TL("VTypeProbes are deprecated. Use fcd-output devices (assigned to the vType) instead."));
1046 bool ok = true;
1047 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1048 SUMOTime period = attrs.getOptPeriod(id.c_str(), ok, SUMOTime_MAX_PERIOD);
1049 std::string type = attrs.getStringSecure(SUMO_ATTR_TYPE, "");
1050 std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1051 if (!ok) {
1052 return;
1053 }
1054 try {
1056 } catch (InvalidArgument& e) {
1057 WRITE_ERROR(e.what());
1058 } catch (IOError& e) {
1059 WRITE_ERROR(e.what());
1060 }
1061}
1062
1063
1064void
1066 bool ok = true;
1067 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1068 SUMOTime period = attrs.getOptPeriod(id.c_str(), ok, SUMOTime_MAX_PERIOD);
1069 SUMOTime begin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, id.c_str(), ok, -1);
1070 std::string edge = attrs.get<std::string>(SUMO_ATTR_EDGE, id.c_str(), ok);
1071 std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1072 const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
1073 if (!ok) {
1074 return;
1075 }
1076 try {
1077 myDetectorBuilder.buildRouteProbe(id, edge, period, begin,
1079 } catch (InvalidArgument& e) {
1080 WRITE_ERROR(e.what());
1081 } catch (IOError& e) {
1082 WRITE_ERROR(e.what());
1083 }
1084}
1085
1086
1087
1088void
1090 myCurrentIsBroken = false;
1091 // check whether this is a detector connected to a tls and optionally to a link
1092 bool ok = true;
1093 const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1094 const std::string lsaid = attrs.getOpt<std::string>(SUMO_ATTR_TLID, id.c_str(), ok, "");
1095 const std::string toLane = attrs.getOpt<std::string>(SUMO_ATTR_TO, id.c_str(), ok, "");
1096 const SUMOTime haltingTimeThreshold = attrs.getOptSUMOTimeReporting(SUMO_ATTR_HALTING_TIME_THRESHOLD, id.c_str(), ok, TIME2STEPS(1));
1097 const double haltingSpeedThreshold = attrs.getOpt<double>(SUMO_ATTR_HALTING_SPEED_THRESHOLD, id.c_str(), ok, 5.0f / 3.6f);
1098 const double jamDistThreshold = attrs.getOpt<double>(SUMO_ATTR_JAM_DIST_THRESHOLD, id.c_str(), ok, 10.0f);
1099 double position = attrs.getOpt<double>(SUMO_ATTR_POSITION, id.c_str(), ok, std::numeric_limits<double>::max());
1100 const double length = attrs.getOpt<double>(SUMO_ATTR_LENGTH, id.c_str(), ok, std::numeric_limits<double>::max());
1101 const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
1102 const bool showDetector = attrs.getOpt<bool>(SUMO_ATTR_SHOW_DETECTOR, id.c_str(), ok, true);
1103 const std::string contStr = attrs.getOpt<std::string>(SUMO_ATTR_CONT, id.c_str(), ok, "");
1104 if (contStr != "") {
1105 WRITE_WARNINGF(TL("Ignoring deprecated argument 'cont' for E2 detector '%'"), id);
1106 }
1107 std::string lane = attrs.getOpt<std::string>(SUMO_ATTR_LANE, id.c_str(), ok, "");
1108 const std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1109 const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
1110 const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
1111 const std::string nextEdges = attrs.getOpt<std::string>(SUMO_ATTR_NEXT_EDGES, id.c_str(), ok, "");
1112
1113 double endPosition = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, id.c_str(), ok, std::numeric_limits<double>::max());
1114 const std::string lanes = attrs.getOpt<std::string>(SUMO_ATTR_LANES, id.c_str(), ok, ""); // lanes has priority to lane
1115 const std::string detectPersonsString = attrs.getOpt<std::string>(SUMO_ATTR_DETECT_PERSONS, id.c_str(), ok, "");
1116 const int detectPersons = parseDetectPersons(detectPersonsString, id, ok);
1117 if (!ok) {
1118 myCurrentIsBroken = true;
1119 return;
1120 }
1121
1122 bool lanesGiven = lanes != "";
1123 bool laneGiven = lane != "";
1124 if (!(lanesGiven || laneGiven)) {
1125 // in absence of any lane-specification assume specification by id
1126 WRITE_WARNING(TL("Trying to specify detector's lane by the given id since the argument 'lane' is missing."))
1127 lane = id;
1128 laneGiven = true;
1129 }
1130 bool lengthGiven = length != std::numeric_limits<double>::max();
1131 bool posGiven = position != std::numeric_limits<double>::max();
1132 bool endPosGiven = endPosition != std::numeric_limits<double>::max();
1133 bool lsaGiven = lsaid != "";
1134 bool toLaneGiven = toLane != "";
1135
1136 MSLane* clane = nullptr;
1137 std::vector<MSLane*> clanes;
1138 if (lanesGiven) {
1139 // If lanes is given, endPos and startPos are required. lane, and length are ignored
1140 std::string seps = " ,\t\n";
1141 StringTokenizer st = StringTokenizer(lanes, seps, true);
1142// std::cout << "Parsing lanes..." << std::endl;
1143 while (st.hasNext()) {
1144 std::string nextLaneID = st.next();
1145// std::cout << "Next: " << nextLaneID << std::endl;
1146 if (nextLaneID.find_first_of(seps) != nextLaneID.npos) {
1147 continue;
1148 }
1149 clane = myDetectorBuilder.getLaneChecking(nextLaneID, SUMO_TAG_E2DETECTOR, id);
1150 clanes.push_back(clane);
1151 }
1152 if (clanes.size() == 0) {
1153 throw InvalidArgument("Malformed argument 'lanes' for E2Detector '" + id + "'.\nSpecify 'lanes' as a sequence of lane-IDs separated by whitespace or comma (',')");
1154 }
1155 if (laneGiven) {
1156 WRITE_WARNING("Ignoring argument 'lane' for E2Detector '" + id + "' since argument 'lanes' was given.\n"
1157 "Usage combinations for positional specification: [lane, pos, length], [lane, endPos, length], or [lanes, pos, endPos]");
1158 }
1159 if (lengthGiven) {
1160 WRITE_WARNING("Ignoring argument 'length' for E2Detector '" + id + "' since argument 'lanes' was given.\n"
1161 "Usage combinations for positional specification: [lane, pos, length], [lane, endPos, length], or [lanes, pos, endPos]");
1162 }
1163 if (!posGiven) {
1164 // assuming start pos == lane start
1165 position = 0;
1166 WRITE_WARNINGF(TL("Missing argument 'pos' for E2Detector '%'. Assuming detector start == lane start of lane '%'."), id, clanes[0]->getID());
1167 }
1168 if (!endPosGiven) {
1169 // assuming end pos == lane end
1170 endPosition = clanes[clanes.size() - 1]->getLength();
1171 WRITE_WARNINGF(TL("Missing argument 'endPos' for E2Detector '%'. Assuming detector end == lane end of lane '%'."), id, clanes[clanes.size() - 1]->getID());
1172 }
1173
1174 } else {
1175 if (!laneGiven) {
1176 std::stringstream ss;
1177 ss << "Missing argument 'lane' for E2Detector '" << id << "'."
1178 << "\nUsage combinations for positional specification: [lane, pos, length], [lane, endPos, length], or [lanes, pos, endPos]";
1179 throw InvalidArgument(ss.str());
1180 }
1182
1183 if (posGiven) {
1184 // start pos is given
1185 if (endPosGiven && lengthGiven) {
1186 std::stringstream ss;
1187 ss << "Ignoring argument 'endPos' for E2Detector '" << id << "' since argument 'pos' was given."
1188 << "\nUsage combinations for positional specification: [lane, pos, length], [lane, endPos, length], or [lanes, pos, endPos]";
1189 WRITE_WARNING(ss.str());
1190 endPosition = std::numeric_limits<double>::max();
1191 }
1192 if (!lengthGiven && !endPosGiven) {
1193 std::stringstream ss;
1194 ss << "Missing arguments 'length'/'endPos' for E2Detector '" << id << "'. Assuming detector end == lane end of lane '" << lane << "'.";
1195 WRITE_WARNING(ss.str());
1196 endPosition = clane->getLength();
1197 }
1198 } else if (endPosGiven) {
1199 // endPos is given, pos is not given
1200 if (!lengthGiven) {
1201 std::stringstream ss;
1202 ss << "Missing arguments 'length'/'pos' for E2Detector '" << id << "'. Assuming detector start == lane start of lane '" << lane << "'.";
1203 WRITE_WARNING(ss.str());
1204 }
1205 } else {
1206 std::stringstream ss;
1207 if (lengthGiven && fabs(length - clane->getLength()) > NUMERICAL_EPS) {
1208 ss << "Incomplete positional specification for E2Detector '" << id << "'."
1209 << "\nUsage combinations for positional specification: [lane, pos, length], [lane, endPos, length], or [lanes, pos, endPos]";
1210 throw InvalidArgument(ss.str());
1211 }
1212 endPosition = clane->getLength();
1213 position = 0;
1214 ss << "Missing arguments 'pos'/'endPos' for E2Detector '" << id << "'. Assuming that the detector covers the whole lane '" << lane << "'.";
1215 WRITE_WARNING(ss.str());
1216 }
1217 }
1218
1219 // Period
1220
1221 SUMOTime period;
1222 if (!lsaGiven) {
1223 period = attrs.getOptPeriod(id.c_str(), ok, SUMOTime_MAX_PERIOD);
1224 if (!ok) {
1225 myCurrentIsBroken = true;
1226 return;
1227 }
1228 } else {
1229 period = attrs.getPeriod(id.c_str(), ok, false);
1230 }
1231
1232 // TLS
1233 MSTLLogicControl::TLSLogicVariants* tlls = nullptr;
1234 if (lsaGiven) {
1235 tlls = &myJunctionControlBuilder.getTLLogic(lsaid);
1236 if (tlls->getActive() == nullptr) {
1237 throw InvalidArgument("The detector '" + id + "' refers to an unknown lsa '" + lsaid + "'.");
1238 }
1239 if (period != -1) {
1240 WRITE_WARNINGF(TL("Ignoring argument 'period' for E2Detector '%' since argument 'tl' was given."), id);
1241 period = -1;
1242 }
1243 }
1244
1245 // Link
1246 MSLane* cToLane = nullptr;
1247 if (toLaneGiven) {
1249 }
1250
1251 // File
1252 std::string filename;
1253 try {
1254 filename = FileHelpers::checkForRelativity(file, getFileName());
1255 } catch (IOError& e) {
1256 WRITE_ERROR(e.what());
1257 }
1258
1259 Parameterised* det;
1260 // Build detector
1261 if (lanesGiven) {
1262 // specification by a lane sequence
1263 det = myDetectorBuilder.buildE2Detector(id, clanes, position, endPosition, filename, period,
1264 haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold,
1265 name, vTypes, nextEdges, detectPersons, friendlyPos, showDetector,
1266 tlls, cToLane);
1267 } else {
1268 // specification by start or end lane
1269 det = myDetectorBuilder.buildE2Detector(id, clane, position, endPosition, length, filename, period,
1270 haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold,
1271 name, vTypes, nextEdges, detectPersons, friendlyPos, showDetector,
1272 tlls, cToLane);
1273 }
1274 myLastParameterised.push_back(det);
1275}
1276
1277
1278void
1280 myCurrentIsBroken = false;
1281 bool ok = true;
1282 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1283 const SUMOTime period = attrs.getOptPeriod(id.c_str(), ok, SUMOTime_MAX_PERIOD);
1284 const SUMOTime haltingTimeThreshold = attrs.getOptSUMOTimeReporting(SUMO_ATTR_HALTING_TIME_THRESHOLD, id.c_str(), ok, TIME2STEPS(1));
1285 const double haltingSpeedThreshold = attrs.getOpt<double>(SUMO_ATTR_HALTING_SPEED_THRESHOLD, id.c_str(), ok, 5.0f / 3.6f);
1286 const std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1287 const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
1288 const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
1289 const std::string nextEdges = attrs.getOpt<std::string>(SUMO_ATTR_NEXT_EDGES, id.c_str(), ok, "");
1290 const bool openEntry = attrs.getOpt<bool>(SUMO_ATTR_OPEN_ENTRY, id.c_str(), ok, false);
1291 const bool expectArrival = attrs.getOpt<bool>(SUMO_ATTR_EXPECT_ARRIVAL, id.c_str(), ok, false);
1292 const std::string detectPersonsString = attrs.getOpt<std::string>(SUMO_ATTR_DETECT_PERSONS, id.c_str(), ok, "");
1293 const int detectPersons = parseDetectPersons(detectPersonsString, id, ok);
1294 if (!ok) {
1295 myCurrentIsBroken = true;
1296 return;
1297 }
1298 try {
1301 period, haltingSpeedThreshold, haltingTimeThreshold, name, vTypes, nextEdges, detectPersons, openEntry, expectArrival);
1302 myLastParameterised.push_back(det);
1303 } catch (InvalidArgument& e) {
1304 myCurrentIsBroken = true;
1305 WRITE_ERROR(e.what());
1306 } catch (IOError& e) {
1307 myCurrentIsBroken = true;
1308 WRITE_ERROR(e.what());
1309 }
1310}
1311
1312
1313void
1315 bool ok = true;
1316 const double position = attrs.get<double>(SUMO_ATTR_POSITION, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
1317 const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, myDetectorBuilder.getCurrentE3ID().c_str(), ok, false);
1318 const std::string lane = attrs.get<std::string>(SUMO_ATTR_LANE, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
1319 if (!ok) {
1320 return;
1321 }
1322 myDetectorBuilder.addE3Entry(lane, position, friendlyPos);
1323}
1324
1325
1326void
1328 bool ok = true;
1329 const double position = attrs.get<double>(SUMO_ATTR_POSITION, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
1330 const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, myDetectorBuilder.getCurrentE3ID().c_str(), ok, false);
1331 const std::string lane = attrs.get<std::string>(SUMO_ATTR_LANE, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
1332 if (!ok) {
1333 return;
1334 }
1335 myDetectorBuilder.addE3Exit(lane, position, friendlyPos);
1336}
1337
1338
1339void
1341 bool ok = true;
1342 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1343 const double maxTravelTime = attrs.getOpt<double>(SUMO_ATTR_MAX_TRAVELTIME, id.c_str(), ok, 100000);
1344 const double minSamples = attrs.getOpt<double>(SUMO_ATTR_MIN_SAMPLES, id.c_str(), ok, 0);
1345 const double haltingSpeedThreshold = attrs.getOpt<double>(SUMO_ATTR_HALTING_SPEED_THRESHOLD, id.c_str(), ok, POSITION_EPS);
1346 const double haltingSpeedThresholdRel = attrs.getOpt<double>(SUMO_ATTR_HALTING_SPEED_THRESHOLD_RELATIVE, id.c_str(), ok, 0);
1347 const std::string excludeEmpty = attrs.getOpt<std::string>(SUMO_ATTR_EXCLUDE_EMPTY, id.c_str(), ok, "false");
1348 const bool withInternal = attrs.getOpt<bool>(SUMO_ATTR_WITH_INTERNAL, id.c_str(), ok, false);
1349 const bool trackVehicles = attrs.getOpt<bool>(SUMO_ATTR_TRACK_VEHICLES, id.c_str(), ok, false);
1350 const std::string detectPersonsString = attrs.getOpt<std::string>(SUMO_ATTR_DETECT_PERSONS, id.c_str(), ok, "");
1351 const std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1352 const std::string type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
1353 std::string vtypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
1354 const std::string writeAttributes = attrs.getOpt<std::string>(SUMO_ATTR_WRITE_ATTRIBUTES, id.c_str(), ok, "");
1355 const SUMOTime period = attrs.getOptPeriod(id.c_str(), ok, -1);
1356 const SUMOTime begin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, id.c_str(), ok, string2time(OptionsCont::getOptions().getString("begin")));
1357 const SUMOTime end = attrs.getOptSUMOTimeReporting(SUMO_ATTR_END, id.c_str(), ok, string2time(OptionsCont::getOptions().getString("end")));
1358 std::vector<std::string> edgeIDs = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_EDGES, id.c_str(), ok);
1359 const std::string edgesFile = attrs.getOpt<std::string>(SUMO_ATTR_EDGESFILE, id.c_str(), ok, "");
1360 const std::string aggregateStr = attrs.getOpt<std::string>(SUMO_ATTR_AGGREGATE, id.c_str(), ok, "false");
1361 AggregateType aggregate = AggregateType::NO;
1362 if (aggregateStr == "taz") {
1363 aggregate = AggregateType::TAZ;
1364 } else if (StringUtils::toBool(aggregateStr)) {
1365 aggregate = AggregateType::YES;
1366 }
1367 if (!ok) {
1368 return;
1369 }
1370 int detectPersons = 0;
1371 for (std::string mode : StringTokenizer(detectPersonsString).getVector()) {
1372 if (SUMOXMLDefinitions::PersonModeValues.hasString(mode)) {
1373 detectPersons |= (int)SUMOXMLDefinitions::PersonModeValues.get(mode);
1374 } else {
1375 WRITE_ERRORF(TL("Invalid person mode '%' in edgeData definition '%'"), mode, id);
1376 return;
1377 }
1378 }
1379 if (edgesFile != "") {
1380 std::ifstream strm(edgesFile.c_str());
1381 if (!strm.good()) {
1382 throw ProcessError("Could not load names of edges for edgeData definition '" + id + "' from '" + edgesFile + "'.");
1383 }
1384 while (strm.good()) {
1385 std::string name;
1386 strm >> name;
1387 // maybe we're loading an edge-selection
1388 if (StringUtils::startsWith(name, "edge:")) {
1389 edgeIDs.push_back(name.substr(5));
1390 } else if (name != "") {
1391 edgeIDs.push_back(name);
1392 }
1393 }
1394 }
1395 std::vector<MSEdge*> edges;
1396 for (const std::string& edgeID : edgeIDs) {
1397 MSEdge* edge = MSEdge::dictionary(edgeID);
1398 if (edge == nullptr) {
1399 WRITE_ERRORF(TL("Unknown edge '%' in edgeData definition '%'"), edgeID, id);
1400 return;
1401 }
1402 edges.push_back(edge);
1403 }
1404 bool useLanes = objecttype == SUMO_TAG_MEANDATA_LANE;
1405 if (useLanes && MSGlobals::gUseMesoSim && !OptionsCont::getOptions().getBool("meso-lane-queue")) {
1406 WRITE_WARNINGF(TL("LaneData '%' requested for mesoscopic simulation but --meso-lane-queue is not active. Falling back to edgeData."), id);
1407 useLanes = false;
1408 }
1409 try {
1410 myDetectorBuilder.createEdgeLaneMeanData(id, period, begin, end,
1411 type, useLanes, excludeEmpty, withInternal, trackVehicles, detectPersons,
1412 maxTravelTime, minSamples, haltingSpeedThreshold, haltingSpeedThresholdRel, vtypes, writeAttributes, edges, aggregate,
1414 } catch (InvalidArgument& e) {
1415 WRITE_ERROR(e.what());
1416 } catch (IOError& e) {
1417 WRITE_ERROR(e.what());
1418 }
1419}
1420
1421
1422void
1424 bool ok = true;
1425 const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
1426 const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
1427 if (!MSGlobals::gUsingInternalLanes && (fromID[0] == ':' || toID[0] == ':')) {
1428 std::string tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, nullptr, ok, "");
1429 if (tlID != "") {
1430 int tlLinkIdx = attrs.get<int>(SUMO_ATTR_TLLINKINDEX, nullptr, ok);
1432 }
1433 return;
1434 }
1435
1436 myCurrentLink = nullptr;
1437 try {
1438 const int fromLaneIdx = attrs.get<int>(SUMO_ATTR_FROM_LANE, nullptr, ok);
1439 const int toLaneIdx = attrs.get<int>(SUMO_ATTR_TO_LANE, nullptr, ok);
1440 LinkDirection dir = parseLinkDir(attrs.get<std::string>(SUMO_ATTR_DIR, nullptr, ok));
1441 LinkState state = parseLinkState(attrs.get<std::string>(SUMO_ATTR_STATE, nullptr, ok));
1442 const double foeVisibilityDistance = attrs.getOpt<double>(SUMO_ATTR_VISIBILITY_DISTANCE, nullptr, ok, state == LINKSTATE_ZIPPER ? 100 : 4.5);
1443 const bool keepClear = attrs.getOpt<bool>(SUMO_ATTR_KEEP_CLEAR, nullptr, ok, true);
1444 const bool indirect = attrs.getOpt<bool>(SUMO_ATTR_INDIRECT, nullptr, ok, false);
1445 std::string tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, nullptr, ok, "");
1446 std::string viaID = attrs.getOpt<std::string>(SUMO_ATTR_VIA, nullptr, ok, "");
1447
1449 if (from == nullptr) {
1450 WRITE_ERRORF(TL("Unknown from-edge '%' in connection."), fromID);
1451 return;
1452 }
1453 myPreviousEdgeIdx = from->getNumericalID();
1454 MSEdge* to = MSEdge::dictionary(toID);
1455 if (to == nullptr) {
1456 WRITE_ERRORF(TL("Unknown to-edge '%' in connection."), toID);
1457 return;
1458 }
1459 if (fromLaneIdx < 0 || fromLaneIdx >= (int)from->getLanes().size() ||
1460 toLaneIdx < 0 || toLaneIdx >= (int)to->getLanes().size()) {
1461 WRITE_ERRORF(TL("Invalid lane index in connection from '%' to '%'."), from->getID(), to->getID());
1462 return;
1463 }
1464 MSLane* fromLane = from->getLanes()[fromLaneIdx];
1465 MSLane* toLane = to->getLanes()[toLaneIdx];
1466 assert(fromLane);
1467 assert(toLane);
1468
1469 MSTrafficLightLogic* logic = nullptr;
1470 int tlLinkIdx = -1;
1471 if (tlID != "") {
1472 tlLinkIdx = attrs.get<int>(SUMO_ATTR_TLLINKINDEX, nullptr, ok);
1473 // make sure that the index is in range
1475 if ((tlLinkIdx < 0 || tlLinkIdx >= (int)logic->getCurrentPhaseDef().getState().size())
1476 && logic->getLogicType() != TrafficLightType::RAIL_SIGNAL
1477 && logic->getLogicType() != TrafficLightType::RAIL_CROSSING) {
1478 WRITE_ERROR("Invalid " + toString(SUMO_ATTR_TLLINKINDEX) + " '" + toString(tlLinkIdx) +
1479 "' in connection controlled by '" + tlID + "'");
1480 return;
1481 }
1482 if (!ok) {
1483 return;
1484 }
1485 }
1486 double length;
1487 // build the link
1488 MSLane* via = nullptr;
1489 if (viaID != "" && MSGlobals::gUsingInternalLanes) {
1490 via = MSLane::dictionary(viaID);
1491 if (via == nullptr) {
1492 WRITE_ERROR("An unknown lane ('" + viaID +
1493 "') should be set as a via-lane for lane '" + toLane->getID() + "'.");
1494 return;
1495 }
1496 length = via->getLength();
1497 } else if (toLane->isCrossing()) {
1498 length = toLane->getLength();
1499 } else {
1500 length = fromLane->getShape()[-1].distanceTo(toLane->getShape()[0]);
1501 }
1502 myCurrentLink = new MSLink(fromLane, toLane, via, dir, state, length, foeVisibilityDistance, keepClear, logic, tlLinkIdx, indirect);
1503 if (via != nullptr) {
1504 via->addIncomingLane(fromLane, myCurrentLink);
1505 } else {
1506 toLane->addIncomingLane(fromLane, myCurrentLink);
1507 }
1508 toLane->addApproachingLane(fromLane, myNetworkVersion < MMVersion(0, 25));
1509
1510 // if a traffic light is responsible for it, inform the traffic light
1511 // check whether this link is controlled by a traffic light
1512 // we can not reuse logic here because it might be an inactive one
1513 if (tlID != "") {
1514 myJunctionControlBuilder.getTLLogic(tlID).addLink(myCurrentLink, fromLane, tlLinkIdx);
1515 }
1516 // add the link
1517 fromLane->addLink(myCurrentLink);
1518
1519 } catch (InvalidArgument& e) {
1520 WRITE_ERROR(e.what());
1521 }
1522}
1523
1524
1525void
1527 if (myCurrentLink == nullptr) {
1528 throw InvalidArgument(toString(SUMO_TAG_CONFLICT) + " must occur within a " + toString(SUMO_TAG_CONNECTION) + " element");
1529 }
1531 return;
1532 }
1533 bool ok = true;
1534 const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
1535 const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
1536 const int fromLaneIdx = attrs.get<int>(SUMO_ATTR_FROM_LANE, nullptr, ok);
1537 const int toLaneIdx = attrs.get<int>(SUMO_ATTR_TO_LANE, nullptr, ok);
1538 double startPos = attrs.get<double>(SUMO_ATTR_STARTPOS, nullptr, ok);
1539 double endPos = attrs.get<double>(SUMO_ATTR_ENDPOS, nullptr, ok);
1540 MSEdge* from = MSEdge::dictionary(fromID);
1541 if (from == nullptr) {
1542 WRITE_ERRORF(TL("Unknown from-edge '%' in conflict."), fromID);
1543 return;
1544 }
1545 MSEdge* to = MSEdge::dictionary(toID);
1546 if (to == nullptr) {
1547 WRITE_ERRORF(TL("Unknown to-edge '%' in conflict."), toID);
1548 return;
1549 }
1550 if (fromLaneIdx < 0 || fromLaneIdx >= (int)from->getLanes().size() ||
1551 toLaneIdx < 0 || toLaneIdx >= (int)to->getLanes().size()) {
1552 WRITE_ERRORF(TL("Invalid lane index in conflict with '%' to '%'."), from->getID(), to->getID());
1553 return;
1554 }
1555 MSLane* fromLane = from->getLanes()[fromLaneIdx];
1556 MSLane* toLane = to->getLanes()[toLaneIdx];
1557 assert(fromLane);
1558 assert(toLane);
1559 myCurrentLink->addCustomConflict(fromLane, toLane, startPos, endPos);
1560}
1561
1562
1564NLHandler::parseLinkDir(const std::string& dir) {
1565 if (SUMOXMLDefinitions::LinkDirections.hasString(dir)) {
1567 } else {
1568 throw InvalidArgument("Unrecognised link direction '" + dir + "'.");
1569 }
1570}
1571
1572
1574NLHandler::parseLinkState(const std::string& state) {
1575 if (SUMOXMLDefinitions::LinkStates.hasString(state)) {
1576 return SUMOXMLDefinitions::LinkStates.get(state);
1577 } else {
1578 if (state == "t") { // legacy networks
1579 // WRITE_WARNING(TL("Obsolete link state 't'. Use 'o' instead"));
1581 } else {
1582 throw InvalidArgument("Unrecognised link state '" + state + "'.");
1583 }
1584 }
1585}
1586
1587
1588// ----------------------------------
1589void
1591 if (myNetIsLoaded) {
1592 //WRITE_WARNING(TL("POIs and Polygons should be loaded using option --po-files"))
1593 return;
1594 }
1595 bool ok = true;
1596 PositionVector s = attrs.get<PositionVector>(SUMO_ATTR_NET_OFFSET, nullptr, ok);
1597 Boundary convBoundary = attrs.get<Boundary>(SUMO_ATTR_CONV_BOUNDARY, nullptr, ok);
1598 Boundary origBoundary = attrs.get<Boundary>(SUMO_ATTR_ORIG_BOUNDARY, nullptr, ok);
1599 std::string proj = attrs.get<std::string>(SUMO_ATTR_ORIG_PROJ, nullptr, ok);
1600 if (ok) {
1601 Position networkOffset = s[0];
1602 GeoConvHelper::init(proj, networkOffset, origBoundary, convBoundary);
1603 if (OptionsCont::getOptions().getBool("fcd-output.geo") && !GeoConvHelper::getFinal().usingGeoProjection()) {
1604 WRITE_WARNING(TL("no valid geo projection loaded from network. fcd-output.geo will not work"));
1605 }
1606 }
1607}
1608
1609
1610void
1612 bool ok = true;
1613 myCurrentIsBroken = false;
1614 // get the id, report an error if not given or empty...
1615 myCurrentDistrictID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1616 if (!ok) {
1617 myCurrentIsBroken = true;
1618 return;
1619 }
1620 try {
1621 const std::string sinkID = myCurrentDistrictID + "-sink";
1622 const std::string sourceID = myCurrentDistrictID + "-source";
1623
1624 MSEdge* sink = MSEdge::dictionary(sinkID);
1625 if (sink == nullptr) {
1626 sink = myEdgeControlBuilder.buildEdge(sinkID, SumoXMLEdgeFunc::CONNECTOR, "", "", "", -1, 0);
1627 MSEdge::dictionary(sinkID, sink);
1628 sink->initialize(new std::vector<MSLane*>());
1629 } else {
1630 if (OptionsCont::getOptions().getBool("junction-taz")
1632 // overwrite junction taz
1634 WRITE_WARNINGF(TL("Replacing junction-taz '%' with loaded TAZ."), myCurrentDistrictID);
1635 } else {
1636 throw InvalidArgument("Another edge with the id '" + sinkID + "' exists.");
1637 }
1638 }
1639 MSEdge* source = MSEdge::dictionary(sourceID);
1640 if (source == nullptr) {
1641 source = myEdgeControlBuilder.buildEdge(sourceID, SumoXMLEdgeFunc::CONNECTOR, "", "", "", -1, 0);
1642 MSEdge::dictionary(sourceID, source);
1643 source->initialize(new std::vector<MSLane*>());
1644 } else {
1645 if (OptionsCont::getOptions().getBool("junction-taz")
1647 // overwrite junction taz
1649 } else {
1650 throw InvalidArgument("Another edge with the id '" + sourceID + "' exists.");
1651 }
1652 }
1653 sink->setOtherTazConnector(source);
1654 source->setOtherTazConnector(sink);
1655 const std::vector<std::string>& desc = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_EDGES, myCurrentDistrictID.c_str(), ok);
1656 for (const std::string& eID : desc) {
1657 MSEdge* edge = MSEdge::dictionary(eID);
1658 // check whether the edge exists
1659 if (edge == nullptr) {
1660 throw InvalidArgument("The edge '" + eID + "' within district '" + myCurrentDistrictID + "' is not known.");
1661 }
1662 source->addSuccessor(edge);
1663 edge->addSuccessor(sink);
1664 }
1665 source->setParameter("taz", myCurrentDistrictID);
1666 sink->setParameter("taz", myCurrentDistrictID);
1667 RGBColor color = attrs.getOpt<RGBColor>(SUMO_ATTR_COLOR, myCurrentDistrictID.c_str(), ok, RGBColor::parseColor("1.0,.33,.33"));
1668 const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, myCurrentDistrictID.c_str(), ok, "");
1669 source->setParameter("tazColor", toString(color));
1670 sink->setParameter("tazColor", toString(color));
1671
1672 if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
1674 const bool fill = attrs.getOpt<bool>(SUMO_ATTR_FILL, myCurrentDistrictID.c_str(), ok, false);
1675 if (shape.size() != 0) {
1676 if (!myNet.getShapeContainer().addPolygon(myCurrentDistrictID, "taz", color, 0, 0, "", shape, false, fill, 1.0, false, name)) {
1677 WRITE_WARNINGF(TL("Skipping visualization of taz '%', polygon already exists."), myCurrentDistrictID);
1678 } else {
1680 myCurrentIsBroken = false;
1681 }
1682 }
1683 }
1684 } catch (InvalidArgument& e) {
1685 WRITE_ERROR(e.what());
1686 myCurrentIsBroken = true;
1687 }
1688}
1689
1690
1691void
1692NLHandler::addDistrictEdge(const SUMOSAXAttributes& attrs, bool isSource) {
1693 if (myCurrentIsBroken) {
1694 // earlier error
1695 return;
1696 }
1697 bool ok = true;
1698 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, myCurrentDistrictID.c_str(), ok);
1699 MSEdge* succ = MSEdge::dictionary(id);
1700 if (succ != nullptr) {
1701 // connect edge
1702 if (isSource) {
1703 MSEdge::dictionary(myCurrentDistrictID + "-source")->addSuccessor(succ);
1704 } else {
1705 succ->addSuccessor(MSEdge::dictionary(myCurrentDistrictID + "-sink"));
1706 }
1707 } else {
1708 WRITE_ERRORF(TL("At district '%': succeeding edge '%' does not exist."), myCurrentDistrictID, id);
1709 }
1710}
1711
1712
1713void
1715 bool ok = true;
1716 const std::vector<std::string>& edgeIDs = attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, nullptr, ok);
1717 if (ok) {
1718 for (const std::string& eID : edgeIDs) {
1719 MSEdge* edge = MSEdge::dictionary(eID);
1720 if (edge == nullptr) {
1721 WRITE_ERRORF(TL("Unknown edge '%' in roundabout"), eID);
1722 } else {
1723 edge->markAsRoundabout();
1724 }
1725 }
1726 }
1727}
1728
1729
1730void
1732 bool ok = true;
1733 std::vector<std::string> signalIDs = attrs.get<std::vector<std::string>>(SUMO_ATTR_SIGNALS, nullptr, ok);
1734 std::vector<const MSRailSignal*> signals;
1735 for (const std::string& id : signalIDs) {
1737 const MSRailSignal* rs = dynamic_cast<const MSRailSignal*>(tll);
1738 if (rs != nullptr) {
1739 signals.push_back(rs);
1740 } else {
1741 throw InvalidArgument("Rail signal '" + toString(id) + "' in " + toString(SUMO_TAG_DEADLOCK) + " is not known");
1742 }
1743 }
1745}
1746
1747
1748void
1750 bool ok = true;
1751 ConstMSEdgeVector edges;
1752 MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_EDGES, "deadlock", ok), edges, "deadlock");
1754}
1755
1756
1757// ----------------------------------
1758void
1760 try {
1762 } catch (InvalidArgument& e) {
1763 WRITE_ERROR(e.what());
1764 }
1765}
1766
1767
1768void
1770 if (!myCurrentIsBroken) {
1771 try {
1773 } catch (InvalidArgument& e) {
1774 WRITE_ERROR(e.what());
1775 myCurrentIsBroken = true;
1776 }
1777 }
1778 myCurrentWAUTID = "";
1779}
1780
1781
1783NLShapeHandler::getLanePos(const std::string& poiID, const std::string& laneID, double lanePos, bool friendlyPos, double lanePosLat) {
1784 MSLane* lane = MSLane::dictionary(laneID);
1785 if (lane == nullptr) {
1786 WRITE_ERRORF(TL("Lane '%' to place poi '%' on is not known."), laneID, poiID);
1787 return Position::INVALID;
1788 }
1789 if (lanePos < 0) {
1790 lanePos = lane->getLength() + lanePos;
1791 }
1792 if ((lanePos < 0) && friendlyPos) {
1793 lanePos = 0;
1794 }
1795 if ((lanePos > lane->getLength()) && friendlyPos) {
1796 lanePos = lane->getLength();
1797 }
1798 if (lanePos < 0 || lanePos > lane->getLength()) {
1799 WRITE_WARNINGF(TL("lane position % for poi '%' is not valid."), toString(lanePos), poiID);
1800 }
1801 return lane->geometryPositionAtOffset(lanePos, -lanePosLat);
1802}
1803
1804
1807 if (rs == nullptr) {
1808 throw InvalidArgument("Rail signal '" + toString((SumoXMLTag)element) + "' constraint must occur within a railSignalConstraints element");
1809 }
1810 bool ok = true;
1811 const std::string tripId = attrs.get<std::string>(SUMO_ATTR_TRIP_ID, nullptr, ok);
1812 const std::string signalID = attrs.get<std::string>(SUMO_ATTR_TLID, nullptr, ok);
1813 const std::string foesString = attrs.get<std::string>(SUMO_ATTR_FOES, nullptr, ok);
1814 const std::vector<std::string> foes = StringTokenizer(foesString).getVector();
1815 const int limit = attrs.getOpt<int>(SUMO_ATTR_LIMIT, nullptr, ok, (int)foes.size());
1816 const bool active = attrs.getOpt<bool>(SUMO_ATTR_ACTIVE, nullptr, ok, true);
1817
1818 if (!MSNet::getInstance()->getTLSControl().knows(signalID)) {
1819 throw InvalidArgument("Rail signal '" + signalID + "' in railSignalConstraints is not known");
1820 }
1821 MSRailSignal* signal = dynamic_cast<MSRailSignal*>(MSNet::getInstance()->getTLSControl().get(signalID).getDefault());
1822 if (signal == nullptr) {
1823 throw InvalidArgument("Traffic light '" + signalID + "' is not a rail signal");
1824 }
1826 switch (element) {
1829 break;
1832 break;
1835 break;
1838 break;
1841 break;
1842 default:
1843 throw InvalidArgument("Unsupported rail signal constraint '" + toString((SumoXMLTag)element) + "'");
1844 }
1845 Parameterised* result = nullptr;
1846 if (ok) {
1847 for (const std::string& foe : foes) {
1848 MSRailSignalConstraint* c = new MSRailSignalConstraint_Predecessor(type, signal, foe, limit, active);
1849 rs->addConstraint(tripId, c);
1850 // XXX if there are multiple foes, only one constraint will receive the parameters
1851 result = c;
1852 }
1853 }
1854 return result;
1855}
1856
1857
1858int
1859NLHandler::parseDetectPersons(const std::string& detectPersonsString, const std::string& id, bool& ok) {
1860 int detectPersons = 0;
1861 for (std::string mode : StringTokenizer(detectPersonsString).getVector()) {
1862 if (SUMOXMLDefinitions::PersonModeValues.hasString(mode)) {
1863 detectPersons |= (int)SUMOXMLDefinitions::PersonModeValues.get(mode);
1864 } else {
1865 WRITE_ERRORF(TL("Invalid person mode '%' in E1 detector definition '%'"), mode, id);
1866 ok = false;
1867 return 0;
1868 }
1869 }
1870 return detectPersons;
1871}
1872
1873
1874/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
std::vector< const MSEdge * > ConstMSEdgeVector
Definition MSEdge.h:75
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:287
#define WRITE_ERRORF(...)
Definition MsgHandler.h:296
#define WRITE_ERROR(msg)
Definition MsgHandler.h:295
#define WRITE_WARNING(msg)
Definition MsgHandler.h:286
#define TL(string)
Definition MsgHandler.h:304
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition SUMOTime.cpp:47
constexpr SUMOTime TIME2STEPS(double x)
Definition SUMOTime.h:60
#define SUMOTime_MAX
Definition SUMOTime.h:34
#define SUMOTime_MAX_PERIOD
Definition SUMOTime.h:36
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.
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_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_PREFERENCE
begin/end of the description of an edge preferences
@ 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_ROUTEPART
@ 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_DEADLOCK
Saved deadlock information, also for loading as an extra check.
@ 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 ...
AggregateType
Numbers representing special SUMO-XML-attribute values Information on edgeData/laneData output should...
@ 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_LATEST_END
The maximum time within the cycle for switching (for coordinated actuation)
@ 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_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_MESO_TLS
@ SUMO_ATTR_AGGREGATE
@ SUMO_ATTR_HALTING_TIME_THRESHOLD
@ SUMO_ATTR_LIMIT
@ SUMO_ATTR_PRIORITY
@ SUMO_ATTR_LANES
@ SUMO_ATTR_VTYPES
@ SUMO_ATTR_SHAPE
edge: the shape in xml-definition
@ SUMO_ATTR_LEFTHAND
@ SUMO_ATTR_SIGNALS
@ SUMO_ATTR_NEXT
succesor phase index
@ SUMO_ATTR_MAX_TRAVELTIME
@ SUMO_ATTR_INCLANES
@ SUMO_ATTR_CHANGE_LEFT
@ SUMO_ATTR_INDEX
@ SUMO_ATTR_VCLASSES
@ 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_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_VISIBILITY_DISTANCE
foe visibility distance of a link
@ SUMO_ATTR_OPEN_ENTRY
@ 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_KEY
@ SUMO_ATTR_REF_TIME
@ SUMO_ATTR_HALTING_SPEED_THRESHOLD_RELATIVE
@ 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_ROUTINGTYPE
@ 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:52
std::pair< int, double > MMVersion
(M)ajor/(M)inor version for written networks and default version for loading
Definition StdDefs.h:71
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:57
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 accessible 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:78
void setOtherTazConnector(const MSEdge *edge)
Definition MSEdge.h:297
void setJunctions(MSJunction *from, MSJunction *to)
Definition MSEdge.cpp:1402
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition MSEdge.h:169
static void parseEdgesList(const std::string &desc, ConstMSEdgeVector &into, const std::string &rid)
Parses the given string assuming it contains a list of edge ids divided by spaces.
Definition MSEdge.cpp:1183
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:1327
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:1144
void initialize(const std::vector< MSLane * > *lanes)
Initialize the edge.
Definition MSEdge.cpp:106
void resetTAZ(MSJunction *junction)
Definition MSEdge.cpp:186
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:1117
void markAsRoundabout()
Definition MSEdge.h:747
static bool gUseMesoSim
Definition MSGlobals.h:106
static bool gLefthand
Whether lefthand-drive is being simulated.
Definition MSGlobals.h:177
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition MSGlobals.h:81
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:2921
void addIncomingLane(MSLane *lane, MSLink *viaLink)
Definition MSLane.cpp:2911
void addLink(MSLink *link)
Delayed initialization.
Definition MSLane.cpp:335
double getLength() const
Returns the lane's length.
Definition MSLane.h:632
bool isCrossing() const
Definition MSLane.cpp:2681
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition MSLane.cpp:2538
virtual const PositionVector & getShape(bool) const
Definition MSLane.h:294
const Position geometryPositionAtOffset(double offset, double lateralOffset=0) const
Definition MSLane.h:561
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:201
void addPreference(const std::string &routingType, SUMOVehicleClass svc, double prio)
add edge type specific routing preference
Definition MSNet.cpp:422
MSTLLogicControl & getTLSControl()
Returns the tls logics control.
Definition MSNet.h:475
MSJunctionControl & getJunctionControl()
Returns the junctions control.
Definition MSNet.h:485
void setPermissionsFound()
Labels the network to contain vehicle class permissions.
Definition MSNet.h:219
ShapeContainer & getShapeContainer()
Returns the shapes container.
Definition MSNet.h:525
void addRestriction(const std::string &id, const SUMOVehicleClass svc, const double speed)
Adds a restriction for an edge type.
Definition MSNet.cpp:376
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.
void loadDeadlockRoute(const ConstMSEdgeVector &edges)
void loadDeadlockCheck(std::vector< const MSRailSignal * > signals)
static MSRailSignalControl & getInstance()
A signal for rails.
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.
MSTrafficLightLogic * getActive(const std::string &id) const
Returns the active program of a named tls.
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.
virtual void inform(std::string msg, bool addType=true)
adds a new error to the list
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
Builds detectors for microsim.
void endE3Detector()
Builds of an e3 detector using collected values.
MSLane * getLaneChecking(const std::string &laneID, SumoXMLTag type, const std::string &detid)
Returns the named lane.
void createEdgeLaneMeanData(const std::string &id, SUMOTime frequency, SUMOTime begin, SUMOTime end, const std::string &type, const bool useLanes, const std::string &excludeEmpty, const bool withInternal, const bool trackVehicles, const int detectPersons, const double maxTravelTime, const double minSamples, const double haltSpeed, const double haltSpeedRel, const std::string &vTypes, const std::string &writeAttributes, std::vector< MSEdge * > edges, AggregateType aggregate, const std::string &device)
Creates edge based mean data collector using the given specification.
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, int detectPersons)
Builds an instantenous induction and adds it to the net.
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.
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, bool mesoTLS, int detectPersons)
Builds an e1 detector 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 * 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, const std::string &routingType, int priority, const std::string &bidi, double distance)
Begins building of an MSEdge.
virtual MSEdge * buildEdge(const std::string &id, const SumoXMLEdgeFunc function, const std::string &streetName, const std::string &edgeType, const std::string &routingType, const int priority, const double distance)
Builds an edge instance (MSEdge in this case)
SumoXMLEdgeFunc getCurrentEdgeFunction() const
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.
void addRequest(const SUMOSAXAttributes &attrs)
adds a request item to the current junction logic
std::vector< Parameterised * > myLastParameterised
Definition NLHandler.h:355
virtual void addE2Detector(const SUMOSAXAttributes &attrs)
Builds an e2 detector using the given specification.
MSLink * myCurrentLink
the link element for the connection currently being parsed
Definition NLHandler.h:385
void addRoundabout(const SUMOSAXAttributes &attrs)
bool myHaveSeenTLSParams
whether tls params were loaded
Definition NLHandler.h:373
void addWAUTSwitch(const SUMOSAXAttributes &attrs)
bool myCurrentIsBroken
Definition NLHandler.h:350
void addE3Entry(const SUMOSAXAttributes &attrs)
Adds an entry to the currently processed e3 detector.
void beginEdgeParsing(const SUMOSAXAttributes &attrs)
begins the processing of an edge
bool myHaveSeenAdditionalSpeedRestrictions
whether additional files contained type-specific speed limits
Definition NLHandler.h:370
std::string myCurrentDistrictID
The id of the current district.
Definition NLHandler.h:333
void addPhase(const SUMOSAXAttributes &attrs)
adds a phase to the traffic lights logic currently build
MMVersion myNetworkVersion
the loaded network version
Definition NLHandler.h:376
std::string myCurrentTypeID
The id of the currently processed edge type.
Definition NLHandler.h:342
void addAssignment(const SUMOSAXAttributes &attrs)
adds a switching condition assignment to the traffic lights logic currently build
static Parameterised * addPredecessorConstraint(int element, const SUMOSAXAttributes &attrs, MSRailSignal *rs)
virtual void addVTypeProbeDetector(const SUMOSAXAttributes &attrs)
Builds a vtype-detector using the given specification.
void addDistrictEdge(const SUMOSAXAttributes &attrs, bool isSource)
std::string myCurrentWAUTID
The id of the currently processed WAUT.
Definition NLHandler.h:339
void parseLanes(const std::string &junctionID, const std::string &def, std::vector< MSLane * > &into, bool &ok)
void addFunction(const SUMOSAXAttributes &attrs)
adds a switching condition function to the traffic lights logic currently build
int myPreviousEdgeIdx
Definition NLHandler.h:391
void addLane(const SUMOSAXAttributes &attrs)
adds a lane to the previously opened edge
void initJunctionLogic(const SUMOSAXAttributes &attrs)
begins the reading of a junction row logic
int parseDetectPersons(const std::string &detectPersonsString, const std::string &id, bool &ok)
Parameterised myLastEdgeParameters
Definition NLHandler.h:354
virtual void myEndElement(int element)
Called when a closing tag occurs.
bool myHaveSeenDefaultLength
whether the loaded network contains edges with default lengths
Definition NLHandler.h:364
NLTriggerBuilder & myTriggerBuilder
The trigger builder to use.
Definition NLHandler.h:324
virtual void addInstantE1Detector(const SUMOSAXAttributes &attrs)
Builds an e1 detector using the given specification.
virtual void openJunction(const SUMOSAXAttributes &attrs)
opens a junction for processing
virtual void endE3Detector()
Builds of an e3 detector using collected values.
bool myAmParsingTLLogicOrJunction
internal information whether a tls-logic is currently read
Definition NLHandler.h:336
JunctionGraph myJunctionGraph
Definition NLHandler.h:389
void addDistrict(const SUMOSAXAttributes &attrs)
bool myCurrentIsInternalToSkip
Information whether the currently parsed edge is internal and not wished, here.
Definition NLHandler.h:317
NLEdgeControlBuilder & myEdgeControlBuilder
The edge builder to use.
Definition NLHandler.h:327
void initTrafficLightLogic(const SUMOSAXAttributes &attrs)
begins the reading of a traffic lights logic
void closeWAUT()
bool myHaveSeenInternalEdge
whether the loaded network contains internal lanes
Definition NLHandler.h:358
NLHandler(const std::string &file, MSNet &net, NLDetectorBuilder &detBuilder, NLTriggerBuilder &triggerBuilder, NLEdgeControlBuilder &edgeBuilder, NLJunctionControlBuilder &junctionBuilder)
Constructor.
Definition NLHandler.cpp:61
void addCondition(const SUMOSAXAttributes &attrs)
adds a switching condition to the traffic lights logic currently build
void setLocation(const SUMOSAXAttributes &attrs)
Parses network location description.
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
Definition NLHandler.cpp:88
bool myHaveSeenNeighs
whether the loaded network contains explicit neighbor lanes
Definition NLHandler.h:367
virtual void openWAUT(const SUMOSAXAttributes &attrs)
LinkState parseLinkState(const std::string &state)
Parses the given character into an enumeration typed link state.
NLDiscreteEventBuilder myActionBuilder
A builder for object actions.
Definition NLHandler.h:314
NLDetectorBuilder & myDetectorBuilder
The detector builder to use.
Definition NLHandler.h:321
void addConflict(const SUMOSAXAttributes &attrs)
NLJunctionControlBuilder & myJunctionControlBuilder
The junction builder to use.
Definition NLHandler.h:330
virtual void addE1Detector(const SUMOSAXAttributes &attrs)
Builds an e1 detector using the given specification.
virtual ~NLHandler()
Destructor.
Definition NLHandler.cpp:84
void addE3Exit(const SUMOSAXAttributes &attrs)
Adds an exit to the currently processed e3 detector.
void beginE3Detector(const SUMOSAXAttributes &attrs)
Starts building of an e3 detector using the given specification.
virtual void closeEdge()
Closes the process of building an edge.
void closeFunction()
adds a switching condition function to the traffic lights logic currently build
bool myHaveJunctionHigherSpeeds
Whether the network was built with higher speed on junctions.
Definition NLHandler.h:361
MSNet & myNet
The net to fill (preinitialised)
Definition NLHandler.h:311
virtual void addDeadlock(const SUMOSAXAttributes &attrs)
Loads deadlock information for preparing additional rail signal checks.
MSRailSignal * myConstrainedSignal
rail signal for which constraints are being loaded
Definition NLHandler.h:382
LinkDirection parseLinkDir(const std::string &dir)
Parses the given character into an enumeration typed link direction.
bool myNetIsLoaded
whether the location element was already loadee
Definition NLHandler.h:379
virtual void addDeadlockRoute(const SUMOSAXAttributes &attrs)
void addWAUTJunction(const SUMOSAXAttributes &attrs)
virtual void addRouteProbeDetector(const SUMOSAXAttributes &attrs)
Builds a routeProbe-detector using the given specification.
virtual void addEdgeLaneMeanData(const SUMOSAXAttributes &attrs, int objecttype)
Builds edge or lane base mean data collector using the given specification.
bool myHaveWarnedAboutInvalidTLType
Definition NLHandler.h:352
void addParam(const SUMOSAXAttributes &attrs)
void addConnection(const SUMOSAXAttributes &attrs)
adds a connection
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
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.
const MSSimpleTrafficLightLogic::Phases & getLoadedPhases() const
return the phases loaded so far (for error reporting and cleanup)
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)
Builds trigger objects for microsim.
void parseAndBuildTractionSubstation(MSNet &net, const SUMOSAXAttributes &attrs)
Parses its values and builds a traction substation.
void addAccess(MSNet &net, const SUMOSAXAttributes &attrs)
Parses the values and adds an access point to the currently parsed stopping place.
void parseAndBuildOverheadWireSegment(MSNet &net, const SUMOSAXAttributes &attrs)
Parses its values and builds an overhead wire segment.
void parseAndBuildCalibrator(MSNet &net, const SUMOSAXAttributes &attrs, const std::string &base)
Parses his values and builds a mesoscopic or microscopic calibrator.
virtual void endParkingArea()
End a parking area.
void parseAndBuildLaneSpeedTrigger(MSNet &net, const SUMOSAXAttributes &attrs, const std::string &base)
Parses his values and builds a lane speed trigger.
void parseAndAddLotEntry(const SUMOSAXAttributes &attrs)
Parses his values and adds a lot entry to current parking area.
void updateParkingAreaDefaultCapacity()
updates the parkingArea default capacity
void buildVaporizer(const SUMOSAXAttributes &attrs)
Builds a vaporization.
void parseAndBuildRerouter(MSNet &net, const SUMOSAXAttributes &attrs)
Parses his values and builds a rerouter.
void parseAndBuildOverheadWireSection(MSNet &net, const SUMOSAXAttributes &attrs)
Parses its values and builds an overhead wire section.
void parseAndBuildChargingStation(MSNet &net, const SUMOSAXAttributes &attrs)
Parses his values and builds a charging station.
void parseAndBuildOverheadWireClamp(MSNet &net, const SUMOSAXAttributes &attrs)
Parses its values and builds an overhead wire clamp.
virtual void endStoppingPlace()
End a stopping place.
MSStoppingPlace * getCurrentStop()
void parseAndBuildStoppingPlace(MSNet &net, const SUMOSAXAttributes &attrs, const SumoXMLTag element)
Parses the values and builds a stopping places for busses, trains or container vehicles.
void parseAndBeginParkingArea(MSNet &net, const SUMOSAXAttributes &attrs)
Parses his values and builds a parking area.
const std::string & getID() const
Returns the id.
Definition Named.h:73
T get(const std::string &id) const
Retrieves an item.
static OptionsCont & getOptions()
Retrieves the options.
An upper class for objects with additional parameters.
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:323
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:267
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 getOptOffsetReporting(int attr, const char *objectid, bool &ok, SUMOTime defaultValue, bool report=true) const
Tries to read given attribute assuming it is a tls offset (SUMOTime or "begin")
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, 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
get key
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.
static bool toBool(const std::string &sData)
converts a string into the bool value described by it by calling the char-type converter
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, cert-dcl58-cpp) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression, cppcoreguidelines-noexcept-swap, performance-noexcept-swap) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition json.hpp:25297