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