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 myHaveSeenMesoEdgeType(false),
79 myHaveSeenTLSParams(false),
80 myNetworkVersion(0, 0),
81 myNetIsLoaded(false) {
82}
83
84
86
87
88void
90 const SUMOSAXAttributes& attrs) {
91 try {
92 switch (element) {
93 case SUMO_TAG_NET: {
94 bool ok;
95 MSGlobals::gLefthand = attrs.getOpt<bool>(SUMO_ATTR_LEFTHAND, nullptr, ok, false);
96 myHaveJunctionHigherSpeeds = attrs.getOpt<bool>(SUMO_ATTR_HIGHER_SPEED, nullptr, ok, false);
97 myNetworkVersion = StringUtils::toVersion(attrs.get<std::string>(SUMO_ATTR_VERSION, nullptr, ok, false));
98 break;
99 }
100 case SUMO_TAG_EDGE:
101 beginEdgeParsing(attrs);
102 break;
103 case SUMO_TAG_LANE:
104 addLane(attrs);
105 break;
106 case SUMO_TAG_NEIGH:
109 }
110 myHaveSeenNeighs = true;
111 break;
113 openJunction(attrs);
114 initJunctionLogic(attrs);
115 break;
116 case SUMO_TAG_PHASE:
117 addPhase(attrs);
118 break;
120 addCondition(attrs);
121 break;
123 addAssignment(attrs);
124 break;
126 addFunction(attrs);
127 break;
129 addConnection(attrs);
130 break;
132 addConflict(attrs);
133 break;
134 case SUMO_TAG_TLLOGIC:
136 break;
137 case SUMO_TAG_REQUEST:
138 addRequest(attrs);
139 break;
140 case SUMO_TAG_WAUT:
141 openWAUT(attrs);
142 break;
144 addWAUTSwitch(attrs);
145 break;
147 addWAUTJunction(attrs);
148 break;
151 addE1Detector(attrs);
152 break;
155 addE2Detector(attrs);
156 break;
159 beginE3Detector(attrs);
160 break;
162 addE3Entry(attrs);
163 break;
165 addE3Exit(attrs);
166 break;
169 break;
170 case SUMO_TAG_VSS:
172 break;
175 break;
178 break;
184 break;
187 break;
191 break;
192 case SUMO_TAG_ACCESS:
194 break;
198 break;
201 break;
204 break;
207 break;
210 break;
213 break;
216 break;
219 break;
222 break;
225 break;
228 break;
230 setLocation(attrs);
231 break;
232 case SUMO_TAG_TAZ:
233 addDistrict(attrs);
234 break;
236 addDistrictEdge(attrs, true);
237 break;
238 case SUMO_TAG_TAZSINK:
239 addDistrictEdge(attrs, false);
240 break;
242 addRoundabout(attrs);
243 break;
244 case SUMO_TAG_TYPE: {
245 bool ok = true;
246 myCurrentTypeID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
247 break;
248 }
250 bool ok = true;
251 const SUMOVehicleClass svc = getVehicleClassID(attrs.get<std::string>(SUMO_ATTR_VCLASS, myCurrentTypeID.c_str(), ok));
252 const double speed = attrs.get<double>(SUMO_ATTR_SPEED, myCurrentTypeID.c_str(), ok);
253 if (ok) {
255 }
256 if (myNetIsLoaded) {
258 }
259 break;
260 }
261 case SUMO_TAG_PREFERENCE: {
262 bool ok = true;
263 const std::string routingType = attrs.get<std::string>(SUMO_ATTR_ROUTINGTYPE, nullptr, ok);
264 const double prio = attrs.get<double>(SUMO_ATTR_PRIORITY, routingType.c_str(), ok);
265 if (prio <= 0) {
266 throw InvalidArgument("In preference for routingType '" + routingType + "', priority must be positve");
267 }
268 if (attrs.hasAttribute(SUMO_ATTR_VCLASSES)) {
269 StringTokenizer st(attrs.get<std::string>(SUMO_ATTR_VCLASSES, routingType.c_str(), ok));
270 for (std::string className : st.getVector()) {
271 myNet.addPreference(routingType, getVehicleClassID(className), prio);
272 }
273 } else if (!attrs.hasAttribute(SUMO_ATTR_VTYPES)) {
274 // general preferenze applying to all types and vClasses
275 myNet.addPreference(routingType, "", prio);
276 }
277 if (attrs.hasAttribute(SUMO_ATTR_VTYPES)) {
278 StringTokenizer st(attrs.get<std::string>(SUMO_ATTR_VTYPES, routingType.c_str(), ok));
279 for (std::string typeName : st.getVector()) {
280 myNet.addPreference(routingType, typeName, prio);
281 }
282 }
283 break;
284 }
285 case SUMO_TAG_MESO: {
286 addMesoEdgeType(attrs);
287 break;
288 }
289 case SUMO_TAG_STOPOFFSET: {
290 bool ok = true;
291 const StopOffset stopOffset(attrs, ok);
292 if (!ok) {
294 } else {
296 }
297 break;
298 }
300 bool ok = true;
301 const std::string signalID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
302 if (!MSNet::getInstance()->getTLSControl().knows(signalID)) {
303 throw InvalidArgument("Rail signal '" + signalID + "' in railSignalConstraints is not known");
304 }
306 if (myConstrainedSignal == nullptr) {
307 throw InvalidArgument("Traffic light '" + signalID + "' is not a rail signal");
308 }
309 break;
310 }
311 case SUMO_TAG_PREDECESSOR: // intended fall-through
312 case SUMO_TAG_FOE_INSERTION: // intended fall-through
313 case SUMO_TAG_INSERTION_PREDECESSOR: // intended fall-through
314 case SUMO_TAG_INSERTION_ORDER: // intended fall-through
317 break;
319 addDeadlock(attrs);
320 break;
321 default:
322 break;
323 }
324 } catch (InvalidArgument& e) {
325 myCurrentIsBroken = true;
326 WRITE_ERROR(e.what());
327 }
328 MSRouteHandler::myStartElement(element, attrs);
329 if (element == SUMO_TAG_PARAM && !myCurrentIsBroken) {
330 addParam(attrs);
331 }
332}
333
334
335void
337 switch (element) {
338 case SUMO_TAG_EDGE:
339 closeEdge();
340 break;
341 case SUMO_TAG_LANE:
344 myLastParameterised.pop_back();
345 }
346 break;
348 if (!myCurrentIsBroken) {
349 try {
351 } catch (InvalidArgument& e) {
352 WRITE_ERROR(e.what());
353 }
354 }
356 break;
357 case SUMO_TAG_TLLOGIC:
358 if (!myCurrentIsBroken) {
359 try {
361 } catch (InvalidArgument& e) {
363 delete phase;
364 }
365 WRITE_ERROR(e.what());
366 }
367 }
369 break;
372 break;
373 case SUMO_TAG_WAUT:
374 closeWAUT();
375 break;
377 myConstrainedSignal = nullptr;
378 break;
384 if (!myCurrentIsBroken) {
385 myLastParameterised.pop_back();
386 }
387 break;
391 if (!myCurrentIsBroken) {
392 myLastParameterised.pop_back();
393 }
394 break;
398 myLastParameterised.pop_back();
399 break;
405 myLastParameterised.pop_back();
406 break;
407 case SUMO_TAG_PREDECESSOR: // intended fall-through
408 case SUMO_TAG_FOE_INSERTION: // intended fall-through
409 case SUMO_TAG_INSERTION_PREDECESSOR: // intended fall-through
410 case SUMO_TAG_INSERTION_ORDER: // intended fall-through
412 myLastParameterised.pop_back();
413 break;
414 case SUMO_TAG_NET:
415 // build junction graph
416 for (JunctionGraph::iterator it = myJunctionGraph.begin(); it != myJunctionGraph.end(); ++it) {
417 MSEdge* edge = MSEdge::dictionary(it->first);
418 MSJunction* from = myJunctionControlBuilder.retrieve(it->second.first);
419 MSJunction* to = myJunctionControlBuilder.retrieve(it->second.second);
420 if (from == nullptr) {
421 WRITE_ERRORF(TL("Unknown from-node '%' for edge '%'."), it->second.first, it->first);
422 return;
423 }
424 if (to == nullptr) {
425 WRITE_ERRORF(TL("Unknown to-node '%' for edge '%'."), it->second.second, it->first);
426 return;
427 }
428 if (edge != nullptr) {
429 edge->setJunctions(from, to);
430 from->addOutgoing(edge);
431 to->addIncoming(edge);
432 }
433 }
434 myNetIsLoaded = true;
435 break;
436 default:
437 break;
438 }
440}
441
442
443
444// ---- the root/edge - element
445void
447 bool ok = true;
448 myCurrentIsBroken = false;
449 // get the id, report an error if not given or empty...
450 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
451 if (!ok) {
452 myCurrentIsBroken = true;
453 return;
454 }
455 // parse the function
457 if (!ok) {
458 myCurrentIsBroken = true;
459 return;
460 }
461 // omit internal edges if not wished
462 if (id[0] == ':') {
466 return;
467 }
468 std::string junctionID = SUMOXMLDefinitions::getJunctionIDFromInternalEdge(id);
469 myJunctionGraph[id] = std::make_pair(junctionID, junctionID);
470 } else {
472 myJunctionGraph[id] = std::make_pair(
473 attrs.get<std::string>(SUMO_ATTR_FROM, id.c_str(), ok),
474 attrs.get<std::string>(SUMO_ATTR_TO, id.c_str(), ok));
475 }
476 if (!ok) {
477 myCurrentIsBroken = true;
478 return;
479 }
481 // get the street name
482 const std::string streetName = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
483 // get the edge type
484 const std::string edgeType = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
485 const std::string routingType = attrs.getOpt<std::string>(SUMO_ATTR_ROUTINGTYPE, id.c_str(), ok, "");
486 // get the edge priority (only for visualization)
487 const int priority = attrs.getOpt<int>(SUMO_ATTR_PRIORITY, id.c_str(), ok, -1); // default taken from netbuild/NBFrame option 'default.priority'
488 // get the bidi-edge
489 const std::string bidi = attrs.getOpt<std::string>(SUMO_ATTR_BIDI, id.c_str(), ok, "");
490 // get the kilometrage/mileage (for visualization and output)
491 const double distance = attrs.getOpt<double>(SUMO_ATTR_DISTANCE, id.c_str(), ok, 0);
492
493 if (!ok) {
494 myCurrentIsBroken = true;
495 return;
496 }
497 //
498 try {
499 myEdgeControlBuilder.beginEdgeParsing(id, func, streetName, edgeType, routingType, priority, bidi, distance);
500 } catch (InvalidArgument& e) {
501 WRITE_ERROR(e.what());
502 myCurrentIsBroken = true;
503 }
504
505 if (func == SumoXMLEdgeFunc::CROSSING) {
506 //get the crossingEdges attribute (to implement the other side of the road pushbutton)
507 const std::string crossingEdges = attrs.getOpt<std::string>(SUMO_ATTR_CROSSING_EDGES, id.c_str(), ok, "");
508 if (!crossingEdges.empty()) {
509 std::vector<std::string> crossingEdgesVector;
510 StringTokenizer edges(crossingEdges);
511 while (edges.hasNext()) {
512 crossingEdgesVector.push_back(edges.next());
513 }
514 myEdgeControlBuilder.addCrossingEdges(crossingEdgesVector);
515 }
516 }
519}
520
521
522void
524 myLastParameterised.clear();
525 // omit internal edges if not wished and broken edges
527 return;
528 }
529 try {
531 MSEdge::dictionary(e->getID(), e);
533 } catch (InvalidArgument& e) {
534 WRITE_ERROR(e.what());
535 }
536}
537
538
539// ---- the root/edge/lanes/lane - element
540void
542 // omit internal edges if not wished and broken edges
544 return;
545 }
546 bool ok = true;
547 // get the id, report an error if not given or empty...
548 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
549 if (!ok) {
550 myCurrentIsBroken = true;
551 return;
552 }
553 const double maxSpeed = attrs.get<double>(SUMO_ATTR_SPEED, id.c_str(), ok);
554 const double friction = attrs.getOpt<double>(SUMO_ATTR_FRICTION, id.c_str(), ok, (double)(1.), false);
555 const double length = attrs.get<double>(SUMO_ATTR_LENGTH, id.c_str(), ok);
556 const std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, id.c_str(), ok, "", false);
557 const std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
558 const std::string changeLeftS = attrs.getOpt<std::string>(SUMO_ATTR_CHANGE_LEFT, id.c_str(), ok, "");
559 const std::string changeRightS = attrs.getOpt<std::string>(SUMO_ATTR_CHANGE_RIGHT, id.c_str(), ok, "");
560 const double width = attrs.getOpt<double>(SUMO_ATTR_WIDTH, id.c_str(), ok, SUMO_const_laneWidth);
561 const PositionVector shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok);
562 const PositionVector outlineShape = attrs.getOpt<PositionVector>(SUMO_ATTR_OUTLINESHAPE, id.c_str(), ok, PositionVector());
563 const int index = attrs.get<int>(SUMO_ATTR_INDEX, id.c_str(), ok);
564 const bool isRampAccel = attrs.getOpt<bool>(SUMO_ATTR_ACCELERATION, id.c_str(), ok, false);
565 const std::string type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
566 if (shape.size() < 2) {
567 WRITE_ERRORF(TL("Shape of lane '%' is broken.\n Can not build according edge."), id);
568 myCurrentIsBroken = true;
569 return;
570 }
571 const SVCPermissions permissions = parseVehicleClasses(allow, disallow, myNetworkVersion);
572 SVCPermissions changeLeft = parseVehicleClasses(changeLeftS, "", myNetworkVersion);
573 SVCPermissions changeRight = parseVehicleClasses(changeRightS, "", myNetworkVersion);
575 // internally, changeLeft always checks for the higher lane index
576 // even though the higher lane index is to the right in a left-hand network
577 std::swap(changeLeft, changeRight);
578 }
579 if (permissions != SVCAll || changeLeft != SVCAll || changeRight != SVCAll) {
581 }
582 myCurrentIsBroken |= !ok;
583 if (!myCurrentIsBroken) {
584 try {
585 MSLane* lane = myEdgeControlBuilder.addLane(id, maxSpeed, friction, length, shape, width, permissions, changeLeft, changeRight, index, isRampAccel, type, outlineShape);
586 // insert the lane into the lane-dictionary, checking
587 if (!MSLane::dictionary(id, lane)) {
588 delete lane;
589 WRITE_ERRORF(TL("Another lane with the id '%' exists."), id);
590 myCurrentIsBroken = true;
591 myLastParameterised.push_back(nullptr);
592 } else {
593 myLastParameterised.push_back(lane);
594 }
595 } catch (InvalidArgument& e) {
596 WRITE_ERROR(e.what());
597 }
598 }
599}
600
601
602// ---- the root/junction - element
603void
605 myCurrentIsBroken = false;
606 bool ok = true;
607 // get the id, report an error if not given or empty...
608 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
609 if (!ok) {
610 myCurrentIsBroken = true;
611 return;
612 }
613 PositionVector shape;
614 if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
615 // inner junctions have no shape
616 shape = attrs.getOpt<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok, PositionVector());
617 if (shape.size() > 2) {
618 shape.closePolygon();
619 }
620 }
621 double x = attrs.get<double>(SUMO_ATTR_X, id.c_str(), ok);
622 double y = attrs.get<double>(SUMO_ATTR_Y, id.c_str(), ok);
623 double z = attrs.getOpt<double>(SUMO_ATTR_Z, id.c_str(), ok, 0);
624 const SumoXMLNodeType type = attrs.get<SumoXMLNodeType>(SUMO_ATTR_TYPE, id.c_str(), ok);
625 std::string key = attrs.getOpt<std::string>(SUMO_ATTR_KEY, id.c_str(), ok, "");
626 std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
627 // incoming lanes
628 std::vector<MSLane*> incomingLanes;
629 parseLanes(id, attrs.getStringSecure(SUMO_ATTR_INCLANES, ""), incomingLanes, ok);
630 // internal lanes
631 std::vector<MSLane*> internalLanes;
633 parseLanes(id, attrs.getStringSecure(SUMO_ATTR_INTLANES, ""), internalLanes, ok);
634 }
635 if (!ok) {
636 myCurrentIsBroken = true;
637 } else {
638 try {
639 myJunctionControlBuilder.openJunction(id, key, type, Position(x, y, z), shape, incomingLanes, internalLanes, name);
640 } catch (InvalidArgument& e) {
641 WRITE_ERROR(e.what() + std::string("\n Can not build according junction."));
642 myCurrentIsBroken = true;
643 }
644 }
645}
646
647
648void
649NLHandler::parseLanes(const std::string& junctionID,
650 const std::string& def, std::vector<MSLane*>& into, bool& ok) {
651 StringTokenizer st(def, " ");
652 while (ok && st.hasNext()) {
653 std::string laneID = st.next();
654 MSLane* lane = MSLane::dictionary(laneID);
655 if (!MSGlobals::gUsingInternalLanes && laneID[0] == ':') {
656 continue;
657 }
658 if (lane == nullptr) {
659 WRITE_ERRORF(TL("An unknown lane ('%') was tried to be set as incoming to junction '%'."), laneID, junctionID);
660 ok = false;
661 continue;
662 }
663 into.push_back(lane);
664 }
665}
666// ----
667
668void
670 bool ok = true;
671 const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
672 // circumventing empty string test
673 const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
674 if (myLastParameterised.size() > 0 && myLastParameterised.back() != nullptr) {
675 myLastParameterised.back()->setParameter(key, val);
676 }
677 // set
679 assert(key != "");
681 if (myNetIsLoaded) {
682 myHaveSeenTLSParams = true;
683 }
684 }
685}
686
687
688void
690 myCurrentIsBroken = false;
691 bool ok = true;
692 // get the id, report an error if not given or empty...
693 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
694 if (!ok) {
695 myCurrentIsBroken = true;
696 return;
697 }
698 SUMOTime refTime = attrs.getOptSUMOTimeReporting(SUMO_ATTR_REF_TIME, id.c_str(), ok, 0);
699 SUMOTime period = attrs.getOptSUMOTimeReporting(SUMO_ATTR_PERIOD, id.c_str(), ok, 0);
700 std::string startProg = attrs.get<std::string>(SUMO_ATTR_START_PROG, id.c_str(), ok);
701 if (!ok) {
702 myCurrentIsBroken = true;
703 }
704 if (!myCurrentIsBroken) {
705 myCurrentWAUTID = id;
706 try {
707 myJunctionControlBuilder.getTLLogicControlToUse().addWAUT(refTime, id, startProg, period);
708 } catch (InvalidArgument& e) {
709 WRITE_ERROR(e.what());
710 myCurrentIsBroken = true;
711 }
712 }
713}
714
715
716void
718 bool ok = true;
720 std::string to = attrs.get<std::string>(SUMO_ATTR_TO, myCurrentWAUTID.c_str(), ok);
721 if (!ok) {
722 myCurrentIsBroken = true;
723 }
724 if (!myCurrentIsBroken) {
725 try {
727 } catch (InvalidArgument& e) {
728 WRITE_ERROR(e.what());
729 myCurrentIsBroken = true;
730 }
731 }
732}
733
734
735void
737 bool ok = true;
738 std::string wautID = attrs.get<std::string>(SUMO_ATTR_WAUT_ID, nullptr, ok);
739 std::string junctionID = attrs.get<std::string>(SUMO_ATTR_JUNCTION_ID, nullptr, ok);
740 std::string procedure = attrs.getOpt<std::string>(SUMO_ATTR_PROCEDURE, nullptr, ok, "");
741 bool synchron = attrs.getOpt<bool>(SUMO_ATTR_SYNCHRON, nullptr, ok, false);
742 if (!ok) {
743 myCurrentIsBroken = true;
744 }
745 try {
746 if (!myCurrentIsBroken) {
747 myJunctionControlBuilder.getTLLogicControlToUse().addWAUTJunction(wautID, junctionID, procedure, synchron);
748 }
749 } catch (InvalidArgument& e) {
750 WRITE_ERROR(e.what());
751 myCurrentIsBroken = true;
752 }
753}
754
755
756void
758 if (myCurrentIsBroken) {
759 return;
760 }
761 bool ok = true;
762 int request = attrs.get<int>(SUMO_ATTR_INDEX, nullptr, ok);
763 bool cont = false;
764 cont = attrs.getOpt<bool>(SUMO_ATTR_CONT, nullptr, ok, false);
765 std::string response = attrs.get<std::string>(SUMO_ATTR_RESPONSE, nullptr, ok);
766 std::string foes = attrs.get<std::string>(SUMO_ATTR_FOES, nullptr, ok);
767 if (!ok) {
768 return;
769 }
770 // store received information
771 if (request >= 0 && response.length() > 0) {
772 try {
773 myJunctionControlBuilder.addLogicItem(request, response, foes, cont);
774 } catch (InvalidArgument& e) {
775 WRITE_ERROR(e.what());
776 }
777 }
778}
779
780
781void
783 if (myCurrentIsBroken) {
784 return;
785 }
787 bool ok = true;
788 // we either a have a junction or a legacy network with ROWLogic
789 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
790 if (ok) {
792 }
793}
794
795
796void
798 myCurrentIsBroken = false;
800 bool ok = true;
801 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
802 std::string programID = attrs.getOpt<std::string>(SUMO_ATTR_PROGRAMID, id.c_str(), ok, "<unknown>");
804 std::string typeS;
805 if (myJunctionControlBuilder.getTLLogicControlToUse().get(id, programID) == nullptr) {
806 // SUMO_ATTR_TYPE is not needed when only modifying the offset of an
807 // existing program
808 typeS = attrs.get<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok);
809 if (!ok) {
810 myCurrentIsBroken = true;
811 return;
812 }
813 if (SUMOXMLDefinitions::TrafficLightTypes.hasString(typeS)) {
815 } else {
816 WRITE_ERRORF(TL("Traffic light '%' has unknown type '%'."), id, typeS);
817 }
820 WRITE_WARNINGF(TL("Traffic light type '%' cannot be used in mesoscopic simulation. Using '%' as fallback."), toString(type), toString(TrafficLightType::STATIC));
822 }
824 }
825 }
826 SUMOTime offset = attrs.getOptOffsetReporting(SUMO_ATTR_OFFSET, id.c_str(), ok, 0);
827 if (offset == SUMOTime_MAX) {
828 offset = string2time(OptionsCont::getOptions().getString("begin"));
829 }
830 if (!ok) {
831 myCurrentIsBroken = true;
832 return;
833 }
834 myJunctionControlBuilder.initTrafficLightLogic(id, programID, type, offset);
835}
836
837
838void
840 // try to get the phase definition
841 bool ok = true;
842 const std::string& id = myJunctionControlBuilder.getActiveKey();
844
846 const std::string state = attrs.get<std::string>(SUMO_ATTR_STATE, nullptr, ok);
847 if (duration == 0) {
848 WRITE_ERROR("Duration of phase " + toString(myJunctionControlBuilder.getLoadedPhases().size())
849 + " for tlLogic '" + myJunctionControlBuilder.getActiveKey()
850 + "' program '" + myJunctionControlBuilder.getActiveSubKey() + "' is zero.");
851 return;
852 }
853 if (!ok) {
854 return;
855 }
856 MSPhaseDefinition* phase = new MSPhaseDefinition(duration, state);
857
858 // if the traffic light is an actuated traffic light, try to get
859 // the minimum and maximum durations
860 phase->minDuration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MINDURATION, id.c_str(), ok, duration);
861 // if minDur is set but not maxDur, assume high maxDur (avoid using the absolute max in case we do some arithmetic later)
862 SUMOTime defaultMaxDur = attrs.hasAttribute(SUMO_ATTR_MINDURATION) ? std::numeric_limits<int>::max() : duration;
863 phase->maxDuration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MAXDURATION, id.c_str(), ok, defaultMaxDur);
864 phase->earliestEnd = attrs.getOptSUMOTimeReporting(SUMO_ATTR_EARLIEST_END, id.c_str(), ok, tDefault);
865 phase->latestEnd = attrs.getOptSUMOTimeReporting(SUMO_ATTR_LATEST_END, id.c_str(), ok, tDefault);
866 phase->nextPhases = attrs.getOpt<std::vector<int> >(SUMO_ATTR_NEXT, id.c_str(), ok);
867 phase->earlyTarget = attrs.getOpt<std::string>(SUMO_ATTR_EARLY_TARGET, id.c_str(), ok);
868 phase->finalTarget = attrs.getOpt<std::string>(SUMO_ATTR_FINAL_TARGET, id.c_str(), ok);
869 phase->name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok);
870
871 phase->vehext = attrs.getOptSUMOTimeReporting(SUMO_ATTR_VEHICLEEXTENSION, id.c_str(), ok, tDefault);
872 phase->yellow = attrs.getOptSUMOTimeReporting(SUMO_ATTR_YELLOW, id.c_str(), ok, tDefault);
873 phase->red = attrs.getOptSUMOTimeReporting(SUMO_ATTR_RED, id.c_str(), ok, tDefault);
874
875 if (attrs.hasAttribute(SUMO_ATTR_TYPE)) {
876 //SOTL attributes
877 //If the type attribute is not present, the parsed phase is of type "undefined" (MSPhaseDefinition constructor),
878 //in this way SOTL traffic light logic can recognize the phase as unsuitable or decides other
879 //behaviors. See SOTL traffic light logic implementations.
880 std::string phaseTypeString;
881 try {
882 phaseTypeString = attrs.get<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, false);
883 } catch (EmptyData&) {
884 MsgHandler::getWarningInstance()->inform("Empty type definition. Assuming phase type as SUMOSOTL_TagAttrDefinitions::SOTL_ATTL_TYPE_TRANSIENT");
885 phase->myTransientNotDecisional = false;
886 }
887 if (phaseTypeString.find("decisional") != std::string::npos) {
888 phase->myTransientNotDecisional = false;
889 } else if (phaseTypeString.find("transient") != std::string::npos) {
890 phase->myTransientNotDecisional = true;
891 } else {
892 MsgHandler::getWarningInstance()->inform("SOTL_ATTL_TYPE_DECISIONAL nor SOTL_ATTL_TYPE_TRANSIENT. Assuming phase type as SUMOSOTL_TagAttrDefinitions::SOTL_ATTL_TYPE_TRANSIENT");
893 phase->myTransientNotDecisional = false;
894 }
895 phase->myCommit = (phaseTypeString.find("commit") != std::string::npos);
896
897 if (phaseTypeString.find("target") != std::string::npos) {
898 std::string delimiter(" ,;");
899 //Phase declared as target, getting targetLanes attribute
900 try {
902 } catch (EmptyData&) {
903 MsgHandler::getErrorInstance()->inform("Missing targetLane definition for the target phase.");
904 delete phase;
905 return;
906 }
907 }
908 }
909
910 if (phase->maxDuration < phase->minDuration) {
911 WRITE_WARNINGF(TL("maxDur % should not be smaller than minDir % in phase of tlLogic %"), phase->maxDuration, phase->minDuration, id);
912 phase->maxDuration = phase->duration;
913 }
914
915 phase->myLastSwitch = string2time(OptionsCont::getOptions().getString("begin")) - 1; // SUMOTime-option
917}
918
919
920void
922 bool ok = true;
923 const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
924 const std::string value = attrs.get<std::string>(SUMO_ATTR_VALUE, id.c_str(), ok);
925 if (!myJunctionControlBuilder.addCondition(id, value)) {
926 WRITE_ERRORF(TL("Duplicate condition '%' in tlLogic '%'"), id, myJunctionControlBuilder.getActiveKey());
927 }
928}
929
930
931void
933 bool ok = true;
934 const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
935 const std::string check = attrs.get<std::string>(SUMO_ATTR_CHECK, nullptr, ok);
936 const std::string value = attrs.get<std::string>(SUMO_ATTR_VALUE, id.c_str(), ok);
937 myJunctionControlBuilder.addAssignment(id, check, value);
938}
939
940
941void
943 bool ok = true;
944 const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
945 const int nArgs = attrs.get<int>(SUMO_ATTR_NARGS, nullptr, ok);
947}
948
949void
953
954void
956 myCurrentIsBroken = false;
957 bool ok = true;
958 // get the id, report an error if not given or empty...
959 const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
960 if (!ok) {
961 myCurrentIsBroken = true;
962 return;
963 }
964 const SUMOTime period = attrs.getOptPeriod(id.c_str(), ok, SUMOTime_MAX_PERIOD);
965 const double position = attrs.get<double>(SUMO_ATTR_POSITION, id.c_str(), ok);
966 const double length = attrs.getOpt<double>(SUMO_ATTR_LENGTH, id.c_str(), ok, 0);
967 const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
968 const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
969 const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
970 const std::string nextEdges = attrs.getOpt<std::string>(SUMO_ATTR_NEXT_EDGES, id.c_str(), ok, "");
971 const std::string lane = attrs.get<std::string>(SUMO_ATTR_LANE, id.c_str(), ok);
972 const std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
973 const std::string detectPersonsString = attrs.getOpt<std::string>(SUMO_ATTR_DETECT_PERSONS, id.c_str(), ok, "");
974 const int detectPersons = parseDetectPersons(detectPersonsString, id, ok);
975 if (!ok) {
976 myCurrentIsBroken = true;
977 return;
978 }
979 try {
980 Parameterised* det = myDetectorBuilder.buildInductLoop(id, lane, position, length, period,
982 friendlyPos, name, vTypes, nextEdges, detectPersons);
983 myLastParameterised.push_back(det);
984 } catch (InvalidArgument& e) {
985 myCurrentIsBroken = true;
986 WRITE_ERROR(e.what());
987 } catch (IOError& e) {
988 myCurrentIsBroken = true;
989 WRITE_ERROR(e.what());
990 }
991}
992
993
994void
996 myCurrentIsBroken = false;
997 bool ok = true;
998 // get the id, report an error if not given or empty...
999 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1000 if (!ok) {
1001 myCurrentIsBroken = true;
1002 return;
1003 }
1004 const double position = attrs.get<double>(SUMO_ATTR_POSITION, id.c_str(), ok);
1005 const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
1006 const std::string lane = attrs.get<std::string>(SUMO_ATTR_LANE, id.c_str(), ok);
1007 const std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1008 const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
1009 const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
1010 const std::string nextEdges = attrs.getOpt<std::string>(SUMO_ATTR_NEXT_EDGES, id.c_str(), ok, "");
1011 const std::string detectPersonsString = attrs.getOpt<std::string>(SUMO_ATTR_DETECT_PERSONS, id.c_str(), ok, "");
1012 const int detectPersons = parseDetectPersons(detectPersonsString, id, ok);
1013 if (!ok) {
1014 myCurrentIsBroken = true;
1015 return;
1016 }
1017 try {
1018 Parameterised* det = myDetectorBuilder.buildInstantInductLoop(id, lane, position, FileHelpers::checkForRelativity(file, getFileName()), friendlyPos, name, vTypes, nextEdges, detectPersons);
1019 myLastParameterised.push_back(det);
1020 } catch (InvalidArgument& e) {
1021 WRITE_ERROR(e.what());
1022 } catch (IOError& e) {
1023 WRITE_ERROR(e.what());
1024 }
1025 myCurrentIsBroken = true;
1026}
1027
1028
1029void
1031 WRITE_WARNING(TL("VTypeProbes are deprecated. Use fcd-output devices (assigned to the vType) instead."));
1032 bool ok = true;
1033 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1034 SUMOTime period = attrs.getOptPeriod(id.c_str(), ok, SUMOTime_MAX_PERIOD);
1035 std::string type = attrs.getStringSecure(SUMO_ATTR_TYPE, "");
1036 std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1037 if (!ok) {
1038 return;
1039 }
1040 try {
1042 } catch (InvalidArgument& e) {
1043 WRITE_ERROR(e.what());
1044 } catch (IOError& e) {
1045 WRITE_ERROR(e.what());
1046 }
1047}
1048
1049
1050void
1052 bool ok = true;
1053 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1054 SUMOTime period = attrs.getOptPeriod(id.c_str(), ok, SUMOTime_MAX_PERIOD);
1055 SUMOTime begin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, id.c_str(), ok, -1);
1056 std::string edge = attrs.get<std::string>(SUMO_ATTR_EDGE, id.c_str(), ok);
1057 std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1058 const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
1059 if (!ok) {
1060 return;
1061 }
1062 try {
1063 myDetectorBuilder.buildRouteProbe(id, edge, period, begin,
1065 } catch (InvalidArgument& e) {
1066 WRITE_ERROR(e.what());
1067 } catch (IOError& e) {
1068 WRITE_ERROR(e.what());
1069 }
1070}
1071
1072
1073
1074void
1076 myCurrentIsBroken = false;
1077 // check whether this is a detector connected to a tls and optionally to a link
1078 bool ok = true;
1079 const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1080 const std::string lsaid = attrs.getOpt<std::string>(SUMO_ATTR_TLID, id.c_str(), ok, "");
1081 const std::string toLane = attrs.getOpt<std::string>(SUMO_ATTR_TO, id.c_str(), ok, "");
1082 const SUMOTime haltingTimeThreshold = attrs.getOptSUMOTimeReporting(SUMO_ATTR_HALTING_TIME_THRESHOLD, id.c_str(), ok, TIME2STEPS(1));
1083 const double haltingSpeedThreshold = attrs.getOpt<double>(SUMO_ATTR_HALTING_SPEED_THRESHOLD, id.c_str(), ok, 5.0f / 3.6f);
1084 const double jamDistThreshold = attrs.getOpt<double>(SUMO_ATTR_JAM_DIST_THRESHOLD, id.c_str(), ok, 10.0f);
1085 double position = attrs.getOpt<double>(SUMO_ATTR_POSITION, id.c_str(), ok, std::numeric_limits<double>::max());
1086 const double length = attrs.getOpt<double>(SUMO_ATTR_LENGTH, id.c_str(), ok, std::numeric_limits<double>::max());
1087 const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
1088 const bool showDetector = attrs.getOpt<bool>(SUMO_ATTR_SHOW_DETECTOR, id.c_str(), ok, true);
1089 const std::string contStr = attrs.getOpt<std::string>(SUMO_ATTR_CONT, id.c_str(), ok, "");
1090 if (contStr != "") {
1091 WRITE_WARNINGF(TL("Ignoring deprecated argument 'cont' for E2 detector '%'"), id);
1092 }
1093 std::string lane = attrs.getOpt<std::string>(SUMO_ATTR_LANE, id.c_str(), ok, "");
1094 const std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1095 const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
1096 const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
1097 const std::string nextEdges = attrs.getOpt<std::string>(SUMO_ATTR_NEXT_EDGES, id.c_str(), ok, "");
1098
1099 double endPosition = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, id.c_str(), ok, std::numeric_limits<double>::max());
1100 const std::string lanes = attrs.getOpt<std::string>(SUMO_ATTR_LANES, id.c_str(), ok, ""); // lanes has priority to lane
1101 const std::string detectPersonsString = attrs.getOpt<std::string>(SUMO_ATTR_DETECT_PERSONS, id.c_str(), ok, "");
1102 const int detectPersons = parseDetectPersons(detectPersonsString, id, ok);
1103 if (!ok) {
1104 myCurrentIsBroken = true;
1105 return;
1106 }
1107
1108 bool lanesGiven = lanes != "";
1109 bool laneGiven = lane != "";
1110 if (!(lanesGiven || laneGiven)) {
1111 // in absence of any lane-specification assume specification by id
1112 WRITE_WARNING(TL("Trying to specify detector's lane by the given id since the argument 'lane' is missing."))
1113 lane = id;
1114 laneGiven = true;
1115 }
1116 bool lengthGiven = length != std::numeric_limits<double>::max();
1117 bool posGiven = position != std::numeric_limits<double>::max();
1118 bool endPosGiven = endPosition != std::numeric_limits<double>::max();
1119 bool lsaGiven = lsaid != "";
1120 bool toLaneGiven = toLane != "";
1121
1122 MSLane* clane = nullptr;
1123 std::vector<MSLane*> clanes;
1124 if (lanesGiven) {
1125 // If lanes is given, endPos and startPos are required. lane, and length are ignored
1126 std::string seps = " ,\t\n";
1127 StringTokenizer st = StringTokenizer(lanes, seps, true);
1128// std::cout << "Parsing lanes..." << std::endl;
1129 while (st.hasNext()) {
1130 std::string nextLaneID = st.next();
1131// std::cout << "Next: " << nextLaneID << std::endl;
1132 if (nextLaneID.find_first_of(seps) != nextLaneID.npos) {
1133 continue;
1134 }
1135 clane = myDetectorBuilder.getLaneChecking(nextLaneID, SUMO_TAG_E2DETECTOR, id);
1136 clanes.push_back(clane);
1137 }
1138 if (clanes.size() == 0) {
1139 throw InvalidArgument("Malformed argument 'lanes' for E2Detector '" + id + "'.\nSpecify 'lanes' as a sequence of lane-IDs separated by whitespace or comma (',')");
1140 }
1141 if (laneGiven) {
1142 WRITE_WARNING("Ignoring argument 'lane' for E2Detector '" + id + "' since argument 'lanes' was given.\n"
1143 "Usage combinations for positional specification: [lane, pos, length], [lane, endPos, length], or [lanes, pos, endPos]");
1144 }
1145 if (lengthGiven) {
1146 WRITE_WARNING("Ignoring argument 'length' for E2Detector '" + id + "' since argument 'lanes' was given.\n"
1147 "Usage combinations for positional specification: [lane, pos, length], [lane, endPos, length], or [lanes, pos, endPos]");
1148 }
1149 if (!posGiven) {
1150 // assuming start pos == lane start
1151 position = 0;
1152 WRITE_WARNINGF(TL("Missing argument 'pos' for E2Detector '%'. Assuming detector start == lane start of lane '%'."), id, clanes[0]->getID());
1153 }
1154 if (!endPosGiven) {
1155 // assuming end pos == lane end
1156 endPosition = clanes[clanes.size() - 1]->getLength();
1157 WRITE_WARNINGF(TL("Missing argument 'endPos' for E2Detector '%'. Assuming detector end == lane end of lane '%'."), id, clanes[clanes.size() - 1]->getID());
1158 }
1159
1160 } else {
1161 if (!laneGiven) {
1162 std::stringstream ss;
1163 ss << "Missing argument 'lane' for E2Detector '" << id << "'."
1164 << "\nUsage combinations for positional specification: [lane, pos, length], [lane, endPos, length], or [lanes, pos, endPos]";
1165 throw InvalidArgument(ss.str());
1166 }
1168
1169 if (posGiven) {
1170 // start pos is given
1171 if (endPosGiven && lengthGiven) {
1172 std::stringstream ss;
1173 ss << "Ignoring argument 'endPos' for E2Detector '" << id << "' since argument 'pos' was given."
1174 << "\nUsage combinations for positional specification: [lane, pos, length], [lane, endPos, length], or [lanes, pos, endPos]";
1175 WRITE_WARNING(ss.str());
1176 endPosition = std::numeric_limits<double>::max();
1177 }
1178 if (!lengthGiven && !endPosGiven) {
1179 std::stringstream ss;
1180 ss << "Missing arguments 'length'/'endPos' for E2Detector '" << id << "'. Assuming detector end == lane end of lane '" << lane << "'.";
1181 WRITE_WARNING(ss.str());
1182 endPosition = clane->getLength();
1183 }
1184 } else if (endPosGiven) {
1185 // endPos is given, pos is not given
1186 if (!lengthGiven) {
1187 std::stringstream ss;
1188 ss << "Missing arguments 'length'/'pos' for E2Detector '" << id << "'. Assuming detector start == lane start of lane '" << lane << "'.";
1189 WRITE_WARNING(ss.str());
1190 }
1191 } else {
1192 std::stringstream ss;
1193 if (lengthGiven && fabs(length - clane->getLength()) > NUMERICAL_EPS) {
1194 ss << "Incomplete positional specification for E2Detector '" << id << "'."
1195 << "\nUsage combinations for positional specification: [lane, pos, length], [lane, endPos, length], or [lanes, pos, endPos]";
1196 throw InvalidArgument(ss.str());
1197 }
1198 endPosition = clane->getLength();
1199 position = 0;
1200 ss << "Missing arguments 'pos'/'endPos' for E2Detector '" << id << "'. Assuming that the detector covers the whole lane '" << lane << "'.";
1201 WRITE_WARNING(ss.str());
1202 }
1203 }
1204
1205 // Period
1206
1207 SUMOTime period;
1208 if (!lsaGiven) {
1209 period = attrs.getOptPeriod(id.c_str(), ok, SUMOTime_MAX_PERIOD);
1210 if (!ok) {
1211 myCurrentIsBroken = true;
1212 return;
1213 }
1214 } else {
1215 period = attrs.getPeriod(id.c_str(), ok, false);
1216 }
1217
1218 // TLS
1219 MSTLLogicControl::TLSLogicVariants* tlls = nullptr;
1220 if (lsaGiven) {
1221 tlls = &myJunctionControlBuilder.getTLLogic(lsaid);
1222 if (tlls->getActive() == nullptr) {
1223 throw InvalidArgument("The detector '" + id + "' refers to an unknown lsa '" + lsaid + "'.");
1224 }
1225 if (period != -1) {
1226 WRITE_WARNINGF(TL("Ignoring argument 'period' for E2Detector '%' since argument 'tl' was given."), id);
1227 period = -1;
1228 }
1229 }
1230
1231 // Link
1232 MSLane* cToLane = nullptr;
1233 if (toLaneGiven) {
1235 }
1236
1237 // File
1238 std::string filename;
1239 try {
1240 filename = FileHelpers::checkForRelativity(file, getFileName());
1241 } catch (IOError& e) {
1242 WRITE_ERROR(e.what());
1243 }
1244
1245 Parameterised* det;
1246 // Build detector
1247 if (lanesGiven) {
1248 // specification by a lane sequence
1249 det = myDetectorBuilder.buildE2Detector(id, clanes, position, endPosition, filename, period,
1250 haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold,
1251 name, vTypes, nextEdges, detectPersons, friendlyPos, showDetector,
1252 tlls, cToLane);
1253 } else {
1254 // specification by start or end lane
1255 det = myDetectorBuilder.buildE2Detector(id, clane, position, endPosition, length, filename, period,
1256 haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold,
1257 name, vTypes, nextEdges, detectPersons, friendlyPos, showDetector,
1258 tlls, cToLane);
1259 }
1260 myLastParameterised.push_back(det);
1261}
1262
1263
1264void
1266 myCurrentIsBroken = false;
1267 bool ok = true;
1268 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1269 const SUMOTime period = attrs.getOptPeriod(id.c_str(), ok, SUMOTime_MAX_PERIOD);
1270 const SUMOTime haltingTimeThreshold = attrs.getOptSUMOTimeReporting(SUMO_ATTR_HALTING_TIME_THRESHOLD, id.c_str(), ok, TIME2STEPS(1));
1271 const double haltingSpeedThreshold = attrs.getOpt<double>(SUMO_ATTR_HALTING_SPEED_THRESHOLD, id.c_str(), ok, 5.0f / 3.6f);
1272 const std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1273 const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
1274 const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
1275 const std::string nextEdges = attrs.getOpt<std::string>(SUMO_ATTR_NEXT_EDGES, id.c_str(), ok, "");
1276 const bool openEntry = attrs.getOpt<bool>(SUMO_ATTR_OPEN_ENTRY, id.c_str(), ok, false);
1277 const bool expectArrival = attrs.getOpt<bool>(SUMO_ATTR_EXPECT_ARRIVAL, id.c_str(), ok, false);
1278 const std::string detectPersonsString = attrs.getOpt<std::string>(SUMO_ATTR_DETECT_PERSONS, id.c_str(), ok, "");
1279 const int detectPersons = parseDetectPersons(detectPersonsString, id, ok);
1280 if (!ok) {
1281 myCurrentIsBroken = true;
1282 return;
1283 }
1284 try {
1287 period, haltingSpeedThreshold, haltingTimeThreshold, name, vTypes, nextEdges, detectPersons, openEntry, expectArrival);
1288 myLastParameterised.push_back(det);
1289 } catch (InvalidArgument& e) {
1290 myCurrentIsBroken = true;
1291 WRITE_ERROR(e.what());
1292 } catch (IOError& e) {
1293 myCurrentIsBroken = true;
1294 WRITE_ERROR(e.what());
1295 }
1296}
1297
1298
1299void
1301 bool ok = true;
1302 const double position = attrs.get<double>(SUMO_ATTR_POSITION, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
1303 const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, myDetectorBuilder.getCurrentE3ID().c_str(), ok, false);
1304 const std::string lane = attrs.get<std::string>(SUMO_ATTR_LANE, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
1305 if (!ok) {
1306 return;
1307 }
1308 myDetectorBuilder.addE3Entry(lane, position, friendlyPos);
1309}
1310
1311
1312void
1314 bool ok = true;
1315 const double position = attrs.get<double>(SUMO_ATTR_POSITION, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
1316 const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, myDetectorBuilder.getCurrentE3ID().c_str(), ok, false);
1317 const std::string lane = attrs.get<std::string>(SUMO_ATTR_LANE, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
1318 if (!ok) {
1319 return;
1320 }
1321 myDetectorBuilder.addE3Exit(lane, position, friendlyPos);
1322}
1323
1324
1325void
1327 bool ok = true;
1328 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1329 const double maxTravelTime = attrs.getOpt<double>(SUMO_ATTR_MAX_TRAVELTIME, id.c_str(), ok, 100000);
1330 const double minSamples = attrs.getOpt<double>(SUMO_ATTR_MIN_SAMPLES, id.c_str(), ok, 0);
1331 const double haltingSpeedThreshold = attrs.getOpt<double>(SUMO_ATTR_HALTING_SPEED_THRESHOLD, id.c_str(), ok, POSITION_EPS);
1332 const std::string excludeEmpty = attrs.getOpt<std::string>(SUMO_ATTR_EXCLUDE_EMPTY, id.c_str(), ok, "false");
1333 const bool withInternal = attrs.getOpt<bool>(SUMO_ATTR_WITH_INTERNAL, id.c_str(), ok, false);
1334 const bool trackVehicles = attrs.getOpt<bool>(SUMO_ATTR_TRACK_VEHICLES, id.c_str(), ok, false);
1335 const std::string detectPersonsString = attrs.getOpt<std::string>(SUMO_ATTR_DETECT_PERSONS, id.c_str(), ok, "");
1336 const std::string file = attrs.get<std::string>(SUMO_ATTR_FILE, id.c_str(), ok);
1337 const std::string type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "performance");
1338 std::string vtypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
1339 const std::string writeAttributes = attrs.getOpt<std::string>(SUMO_ATTR_WRITE_ATTRIBUTES, id.c_str(), ok, "");
1340 const SUMOTime period = attrs.getOptPeriod(id.c_str(), ok, -1);
1341 const SUMOTime begin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, id.c_str(), ok, string2time(OptionsCont::getOptions().getString("begin")));
1342 const SUMOTime end = attrs.getOptSUMOTimeReporting(SUMO_ATTR_END, id.c_str(), ok, string2time(OptionsCont::getOptions().getString("end")));
1343 std::vector<std::string> edgeIDs = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_EDGES, id.c_str(), ok);
1344 const std::string edgesFile = attrs.getOpt<std::string>(SUMO_ATTR_EDGESFILE, id.c_str(), ok, "");
1345 const std::string aggregateStr = attrs.getOpt<std::string>(SUMO_ATTR_AGGREGATE, id.c_str(), ok, "false");
1346 AggregateType aggregate = AggregateType::NO;
1347 if (aggregateStr == "taz") {
1348 aggregate = AggregateType::TAZ;
1349 } else if (StringUtils::toBool(aggregateStr)) {
1350 aggregate = AggregateType::YES;
1351 }
1352 if (!ok) {
1353 return;
1354 }
1355 int detectPersons = 0;
1356 for (std::string mode : StringTokenizer(detectPersonsString).getVector()) {
1357 if (SUMOXMLDefinitions::PersonModeValues.hasString(mode)) {
1358 detectPersons |= (int)SUMOXMLDefinitions::PersonModeValues.get(mode);
1359 } else {
1360 WRITE_ERRORF(TL("Invalid person mode '%' in edgeData definition '%'"), mode, id);
1361 return;
1362 }
1363 }
1364 if (edgesFile != "") {
1365 std::ifstream strm(edgesFile.c_str());
1366 if (!strm.good()) {
1367 throw ProcessError("Could not load names of edges for edgeData definition '" + id + "' from '" + edgesFile + "'.");
1368 }
1369 while (strm.good()) {
1370 std::string name;
1371 strm >> name;
1372 // maybe we're loading an edge-selection
1373 if (StringUtils::startsWith(name, "edge:")) {
1374 edgeIDs.push_back(name.substr(5));
1375 } else if (name != "") {
1376 edgeIDs.push_back(name);
1377 }
1378 }
1379 }
1380 std::vector<MSEdge*> edges;
1381 for (const std::string& edgeID : edgeIDs) {
1382 MSEdge* edge = MSEdge::dictionary(edgeID);
1383 if (edge == nullptr) {
1384 WRITE_ERRORF(TL("Unknown edge '%' in edgeData definition '%'"), edgeID, id);
1385 return;
1386 }
1387 edges.push_back(edge);
1388 }
1389 bool useLanes = objecttype == SUMO_TAG_MEANDATA_LANE;
1390 if (useLanes && MSGlobals::gUseMesoSim && !OptionsCont::getOptions().getBool("meso-lane-queue")) {
1391 WRITE_WARNINGF(TL("LaneData '%' requested for mesoscopic simulation but --meso-lane-queue is not active. Falling back to edgeData."), id);
1392 useLanes = false;
1393 }
1394 try {
1395 myDetectorBuilder.createEdgeLaneMeanData(id, period, begin, end,
1396 type, useLanes,
1397 // equivalent to TplConvert::_2bool used in SUMOSAXAttributes::getBool
1398 excludeEmpty[0] != 't' && excludeEmpty[0] != 'T' && excludeEmpty[0] != '1' && excludeEmpty[0] != 'x',
1399 excludeEmpty == "defaults", withInternal, trackVehicles, detectPersons,
1400 maxTravelTime, minSamples, haltingSpeedThreshold, vtypes, writeAttributes, edges, aggregate,
1402 } catch (InvalidArgument& e) {
1403 WRITE_ERROR(e.what());
1404 } catch (IOError& e) {
1405 WRITE_ERROR(e.what());
1406 }
1407}
1408
1409
1410void
1412 bool ok = true;
1413 const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
1414 const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
1415 if (!MSGlobals::gUsingInternalLanes && (fromID[0] == ':' || toID[0] == ':')) {
1416 std::string tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, nullptr, ok, "");
1417 if (tlID != "") {
1418 int tlLinkIdx = attrs.get<int>(SUMO_ATTR_TLLINKINDEX, nullptr, ok);
1420 }
1421 return;
1422 }
1423
1424 myCurrentLink = nullptr;
1425 try {
1426 const int fromLaneIdx = attrs.get<int>(SUMO_ATTR_FROM_LANE, nullptr, ok);
1427 const int toLaneIdx = attrs.get<int>(SUMO_ATTR_TO_LANE, nullptr, ok);
1428 LinkDirection dir = parseLinkDir(attrs.get<std::string>(SUMO_ATTR_DIR, nullptr, ok));
1429 LinkState state = parseLinkState(attrs.get<std::string>(SUMO_ATTR_STATE, nullptr, ok));
1430 const double foeVisibilityDistance = attrs.getOpt<double>(SUMO_ATTR_VISIBILITY_DISTANCE, nullptr, ok, state == LINKSTATE_ZIPPER ? 100 : 4.5);
1431 const bool keepClear = attrs.getOpt<bool>(SUMO_ATTR_KEEP_CLEAR, nullptr, ok, true);
1432 const bool indirect = attrs.getOpt<bool>(SUMO_ATTR_INDIRECT, nullptr, ok, false);
1433 std::string tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, nullptr, ok, "");
1434 std::string viaID = attrs.getOpt<std::string>(SUMO_ATTR_VIA, nullptr, ok, "");
1435
1437 if (from == nullptr) {
1438 WRITE_ERRORF(TL("Unknown from-edge '%' in connection."), fromID);
1439 return;
1440 }
1441 myPreviousEdgeIdx = from->getNumericalID();
1442 MSEdge* to = MSEdge::dictionary(toID);
1443 if (to == nullptr) {
1444 WRITE_ERRORF(TL("Unknown to-edge '%' in connection."), toID);
1445 return;
1446 }
1447 if (fromLaneIdx < 0 || fromLaneIdx >= (int)from->getLanes().size() ||
1448 toLaneIdx < 0 || toLaneIdx >= (int)to->getLanes().size()) {
1449 WRITE_ERRORF(TL("Invalid lane index in connection from '%' to '%'."), from->getID(), to->getID());
1450 return;
1451 }
1452 MSLane* fromLane = from->getLanes()[fromLaneIdx];
1453 MSLane* toLane = to->getLanes()[toLaneIdx];
1454 assert(fromLane);
1455 assert(toLane);
1456
1457 MSTrafficLightLogic* logic = nullptr;
1458 int tlLinkIdx = -1;
1459 if (tlID != "") {
1460 tlLinkIdx = attrs.get<int>(SUMO_ATTR_TLLINKINDEX, nullptr, ok);
1461 // make sure that the index is in range
1463 if ((tlLinkIdx < 0 || tlLinkIdx >= (int)logic->getCurrentPhaseDef().getState().size())
1464 && logic->getLogicType() != TrafficLightType::RAIL_SIGNAL
1465 && logic->getLogicType() != TrafficLightType::RAIL_CROSSING) {
1466 WRITE_ERROR("Invalid " + toString(SUMO_ATTR_TLLINKINDEX) + " '" + toString(tlLinkIdx) +
1467 "' in connection controlled by '" + tlID + "'");
1468 return;
1469 }
1470 if (!ok) {
1471 return;
1472 }
1473 }
1474 double length;
1475 // build the link
1476 MSLane* via = nullptr;
1477 if (viaID != "" && MSGlobals::gUsingInternalLanes) {
1478 via = MSLane::dictionary(viaID);
1479 if (via == nullptr) {
1480 WRITE_ERROR("An unknown lane ('" + viaID +
1481 "') should be set as a via-lane for lane '" + toLane->getID() + "'.");
1482 return;
1483 }
1484 length = via->getLength();
1485 } else if (toLane->isCrossing()) {
1486 length = toLane->getLength();
1487 } else {
1488 length = fromLane->getShape()[-1].distanceTo(toLane->getShape()[0]);
1489 }
1490 myCurrentLink = new MSLink(fromLane, toLane, via, dir, state, length, foeVisibilityDistance, keepClear, logic, tlLinkIdx, indirect);
1491 if (via != nullptr) {
1492 via->addIncomingLane(fromLane, myCurrentLink);
1493 } else {
1494 toLane->addIncomingLane(fromLane, myCurrentLink);
1495 }
1496 toLane->addApproachingLane(fromLane, myNetworkVersion < MMVersion(0, 25));
1497
1498 // if a traffic light is responsible for it, inform the traffic light
1499 // check whether this link is controlled by a traffic light
1500 // we can not reuse logic here because it might be an inactive one
1501 if (tlID != "") {
1502 myJunctionControlBuilder.getTLLogic(tlID).addLink(myCurrentLink, fromLane, tlLinkIdx);
1503 }
1504 // add the link
1505 fromLane->addLink(myCurrentLink);
1506
1507 } catch (InvalidArgument& e) {
1508 WRITE_ERROR(e.what());
1509 }
1510}
1511
1512
1513void
1515 if (myCurrentLink == nullptr) {
1516 throw InvalidArgument(toString(SUMO_TAG_CONFLICT) + " must occur within a " + toString(SUMO_TAG_CONNECTION) + " element");
1517 }
1519 return;
1520 }
1521 bool ok = true;
1522 const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
1523 const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
1524 const int fromLaneIdx = attrs.get<int>(SUMO_ATTR_FROM_LANE, nullptr, ok);
1525 const int toLaneIdx = attrs.get<int>(SUMO_ATTR_TO_LANE, nullptr, ok);
1526 double startPos = attrs.get<double>(SUMO_ATTR_STARTPOS, nullptr, ok);
1527 double endPos = attrs.get<double>(SUMO_ATTR_ENDPOS, nullptr, ok);
1528 MSEdge* from = MSEdge::dictionary(fromID);
1529 if (from == nullptr) {
1530 WRITE_ERRORF(TL("Unknown from-edge '%' in conflict."), fromID);
1531 return;
1532 }
1533 MSEdge* to = MSEdge::dictionary(toID);
1534 if (to == nullptr) {
1535 WRITE_ERRORF(TL("Unknown to-edge '%' in conflict."), toID);
1536 return;
1537 }
1538 if (fromLaneIdx < 0 || fromLaneIdx >= (int)from->getLanes().size() ||
1539 toLaneIdx < 0 || toLaneIdx >= (int)to->getLanes().size()) {
1540 WRITE_ERRORF(TL("Invalid lane index in conflict with '%' to '%'."), from->getID(), to->getID());
1541 return;
1542 }
1543 MSLane* fromLane = from->getLanes()[fromLaneIdx];
1544 MSLane* toLane = to->getLanes()[toLaneIdx];
1545 assert(fromLane);
1546 assert(toLane);
1547 myCurrentLink->addCustomConflict(fromLane, toLane, startPos, endPos);
1548}
1549
1550
1552NLHandler::parseLinkDir(const std::string& dir) {
1553 if (SUMOXMLDefinitions::LinkDirections.hasString(dir)) {
1555 } else {
1556 throw InvalidArgument("Unrecognised link direction '" + dir + "'.");
1557 }
1558}
1559
1560
1562NLHandler::parseLinkState(const std::string& state) {
1563 if (SUMOXMLDefinitions::LinkStates.hasString(state)) {
1564 return SUMOXMLDefinitions::LinkStates.get(state);
1565 } else {
1566 if (state == "t") { // legacy networks
1567 // WRITE_WARNING(TL("Obsolete link state 't'. Use 'o' instead"));
1569 } else {
1570 throw InvalidArgument("Unrecognised link state '" + state + "'.");
1571 }
1572 }
1573}
1574
1575
1576// ----------------------------------
1577void
1579 if (myNetIsLoaded) {
1580 //WRITE_WARNING(TL("POIs and Polygons should be loaded using option --po-files"))
1581 return;
1582 }
1583 bool ok = true;
1584 PositionVector s = attrs.get<PositionVector>(SUMO_ATTR_NET_OFFSET, nullptr, ok);
1585 Boundary convBoundary = attrs.get<Boundary>(SUMO_ATTR_CONV_BOUNDARY, nullptr, ok);
1586 Boundary origBoundary = attrs.get<Boundary>(SUMO_ATTR_ORIG_BOUNDARY, nullptr, ok);
1587 std::string proj = attrs.get<std::string>(SUMO_ATTR_ORIG_PROJ, nullptr, ok);
1588 if (ok) {
1589 Position networkOffset = s[0];
1590 GeoConvHelper::init(proj, networkOffset, origBoundary, convBoundary);
1591 if (OptionsCont::getOptions().getBool("fcd-output.geo") && !GeoConvHelper::getFinal().usingGeoProjection()) {
1592 WRITE_WARNING(TL("no valid geo projection loaded from network. fcd-output.geo will not work"));
1593 }
1594 }
1595}
1596
1597
1598void
1600 bool ok = true;
1601 myCurrentIsBroken = false;
1602 // get the id, report an error if not given or empty...
1603 myCurrentDistrictID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
1604 if (!ok) {
1605 myCurrentIsBroken = true;
1606 return;
1607 }
1608 try {
1609 const std::string sinkID = myCurrentDistrictID + "-sink";
1610 const std::string sourceID = myCurrentDistrictID + "-source";
1611
1612 MSEdge* sink = MSEdge::dictionary(sinkID);
1613 if (sink == nullptr) {
1614 sink = myEdgeControlBuilder.buildEdge(sinkID, SumoXMLEdgeFunc::CONNECTOR, "", "", "", -1, 0);
1615 MSEdge::dictionary(sinkID, sink);
1616 sink->initialize(new std::vector<MSLane*>());
1617 } else {
1618 if (OptionsCont::getOptions().getBool("junction-taz")
1620 // overwrite junction taz
1622 WRITE_WARNINGF(TL("Replacing junction-taz '%' with loaded TAZ."), myCurrentDistrictID);
1623 } else {
1624 throw InvalidArgument("Another edge with the id '" + sinkID + "' exists.");
1625 }
1626 }
1627 MSEdge* source = MSEdge::dictionary(sourceID);
1628 if (source == nullptr) {
1629 source = myEdgeControlBuilder.buildEdge(sourceID, SumoXMLEdgeFunc::CONNECTOR, "", "", "", -1, 0);
1630 MSEdge::dictionary(sourceID, source);
1631 source->initialize(new std::vector<MSLane*>());
1632 } else {
1633 if (OptionsCont::getOptions().getBool("junction-taz")
1635 // overwrite junction taz
1637 } else {
1638 throw InvalidArgument("Another edge with the id '" + sourceID + "' exists.");
1639 }
1640 }
1641 sink->setOtherTazConnector(source);
1642 source->setOtherTazConnector(sink);
1643 const std::vector<std::string>& desc = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_EDGES, myCurrentDistrictID.c_str(), ok);
1644 for (const std::string& eID : desc) {
1645 MSEdge* edge = MSEdge::dictionary(eID);
1646 // check whether the edge exists
1647 if (edge == nullptr) {
1648 throw InvalidArgument("The edge '" + eID + "' within district '" + myCurrentDistrictID + "' is not known.");
1649 }
1650 source->addSuccessor(edge);
1651 edge->addSuccessor(sink);
1652 }
1653 source->setParameter("taz", myCurrentDistrictID);
1654 sink->setParameter("taz", myCurrentDistrictID);
1655 RGBColor color = attrs.getOpt<RGBColor>(SUMO_ATTR_COLOR, myCurrentDistrictID.c_str(), ok, RGBColor::parseColor("1.0,.33,.33"));
1656 const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, myCurrentDistrictID.c_str(), ok, "");
1657 source->setParameter("tazColor", toString(color));
1658 sink->setParameter("tazColor", toString(color));
1659
1660 if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
1662 const bool fill = attrs.getOpt<bool>(SUMO_ATTR_FILL, myCurrentDistrictID.c_str(), ok, false);
1663 if (shape.size() != 0) {
1664 if (!myNet.getShapeContainer().addPolygon(myCurrentDistrictID, "taz", color, 0, 0, "", shape, false, fill, 1.0, false, name)) {
1665 WRITE_WARNINGF(TL("Skipping visualization of taz '%', polygon already exists."), myCurrentDistrictID);
1666 } else {
1668 myCurrentIsBroken = false;
1669 }
1670 }
1671 }
1672 } catch (InvalidArgument& e) {
1673 WRITE_ERROR(e.what());
1674 myCurrentIsBroken = true;
1675 }
1676}
1677
1678
1679void
1680NLHandler::addDistrictEdge(const SUMOSAXAttributes& attrs, bool isSource) {
1681 if (myCurrentIsBroken) {
1682 // earlier error
1683 return;
1684 }
1685 bool ok = true;
1686 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, myCurrentDistrictID.c_str(), ok);
1687 MSEdge* succ = MSEdge::dictionary(id);
1688 if (succ != nullptr) {
1689 // connect edge
1690 if (isSource) {
1691 MSEdge::dictionary(myCurrentDistrictID + "-source")->addSuccessor(succ);
1692 } else {
1693 succ->addSuccessor(MSEdge::dictionary(myCurrentDistrictID + "-sink"));
1694 }
1695 } else {
1696 WRITE_ERRORF(TL("At district '%': succeeding edge '%' does not exist."), myCurrentDistrictID, id);
1697 }
1698}
1699
1700
1701void
1703 bool ok = true;
1704 const std::vector<std::string>& edgeIDs = attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, nullptr, ok);
1705 if (ok) {
1706 for (const std::string& eID : edgeIDs) {
1707 MSEdge* edge = MSEdge::dictionary(eID);
1708 if (edge == nullptr) {
1709 WRITE_ERRORF(TL("Unknown edge '%' in roundabout"), eID);
1710 } else {
1711 edge->markAsRoundabout();
1712 }
1713 }
1714 }
1715}
1716
1717
1718void
1720 bool ok = true;
1721 MESegment::MesoEdgeType edgeType = myNet.getMesoType(""); // init defaults
1722 edgeType.tauff = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MESO_TAUFF, myCurrentTypeID.c_str(), ok, edgeType.tauff);
1723 edgeType.taufj = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MESO_TAUFJ, myCurrentTypeID.c_str(), ok, edgeType.taufj);
1724 edgeType.taujf = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MESO_TAUJF, myCurrentTypeID.c_str(), ok, edgeType.taujf);
1725 edgeType.taujj = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MESO_TAUJJ, myCurrentTypeID.c_str(), ok, edgeType.taujj);
1726 edgeType.jamThreshold = attrs.getOpt<double>(SUMO_ATTR_JAM_DIST_THRESHOLD, myCurrentTypeID.c_str(), ok, edgeType.jamThreshold);
1727 edgeType.junctionControl = attrs.getOpt<bool>(SUMO_ATTR_MESO_JUNCTION_CONTROL, myCurrentTypeID.c_str(), ok, edgeType.junctionControl);
1728 edgeType.tlsPenalty = attrs.getOpt<double>(SUMO_ATTR_MESO_TLS_PENALTY, myCurrentTypeID.c_str(), ok, edgeType.tlsPenalty);
1729 edgeType.tlsFlowPenalty = attrs.getOpt<double>(SUMO_ATTR_MESO_TLS_FLOW_PENALTY, myCurrentTypeID.c_str(), ok, edgeType.tlsFlowPenalty);
1731 edgeType.overtaking = attrs.getOpt<bool>(SUMO_ATTR_MESO_OVERTAKING, myCurrentTypeID.c_str(), ok, edgeType.overtaking);
1732
1733 if (ok) {
1735 }
1736 if (myNetIsLoaded) {
1738 }
1739}
1740
1741void
1743 bool ok = true;
1744 std::vector<std::string> signalIDs = attrs.get<std::vector<std::string>>(SUMO_ATTR_SIGNALS, nullptr, ok);
1745 std::vector<const MSRailSignal*> signals;
1746 for (const std::string& id : signalIDs) {
1748 const MSRailSignal* rs = dynamic_cast<const MSRailSignal*>(tll);
1749 if (rs != nullptr) {
1750 signals.push_back(rs);
1751 } else {
1752 throw InvalidArgument("Rail signal '" + toString(id) + "' in " + toString(SUMO_TAG_DEADLOCK) + " is not known");
1753 }
1754 }
1756}
1757
1758// ----------------------------------
1759void
1761 try {
1763 } catch (InvalidArgument& e) {
1764 WRITE_ERROR(e.what());
1765 }
1766}
1767
1768
1769void
1771 if (!myCurrentIsBroken) {
1772 try {
1774 } catch (InvalidArgument& e) {
1775 WRITE_ERROR(e.what());
1776 myCurrentIsBroken = true;
1777 }
1778 }
1779 myCurrentWAUTID = "";
1780}
1781
1782
1784NLShapeHandler::getLanePos(const std::string& poiID, const std::string& laneID, double lanePos, bool friendlyPos, double lanePosLat) {
1785 MSLane* lane = MSLane::dictionary(laneID);
1786 if (lane == nullptr) {
1787 WRITE_ERRORF(TL("Lane '%' to place poi '%' on is not known."), laneID, poiID);
1788 return Position::INVALID;
1789 }
1790 if (lanePos < 0) {
1791 lanePos = lane->getLength() + lanePos;
1792 }
1793 if ((lanePos < 0) && friendlyPos) {
1794 lanePos = 0;
1795 }
1796 if ((lanePos > lane->getLength()) && friendlyPos) {
1797 lanePos = lane->getLength();
1798 }
1799 if (lanePos < 0 || lanePos > lane->getLength()) {
1800 WRITE_WARNINGF(TL("lane position % for poi '%' is not valid."), toString(lanePos), poiID);
1801 }
1802 return lane->geometryPositionAtOffset(lanePos, -lanePosLat);
1803}
1804
1805
1808 if (rs == nullptr) {
1809 throw InvalidArgument("Rail signal '" + toString((SumoXMLTag)element) + "' constraint must occur within a railSignalConstraints element");
1810 }
1811 bool ok = true;
1812 const std::string tripId = attrs.get<std::string>(SUMO_ATTR_TRIP_ID, nullptr, ok);
1813 const std::string signalID = attrs.get<std::string>(SUMO_ATTR_TLID, nullptr, ok);
1814 const std::string foesString = attrs.get<std::string>(SUMO_ATTR_FOES, nullptr, ok);
1815 const std::vector<std::string> foes = StringTokenizer(foesString).getVector();
1816 const int limit = attrs.getOpt<int>(SUMO_ATTR_LIMIT, nullptr, ok, (int)foes.size());
1817 const bool active = attrs.getOpt<bool>(SUMO_ATTR_ACTIVE, nullptr, ok, true);
1818
1819 if (!MSNet::getInstance()->getTLSControl().knows(signalID)) {
1820 throw InvalidArgument("Rail signal '" + signalID + "' in railSignalConstraints is not known");
1821 }
1822 MSRailSignal* signal = dynamic_cast<MSRailSignal*>(MSNet::getInstance()->getTLSControl().get(signalID).getDefault());
1823 if (signal == nullptr) {
1824 throw InvalidArgument("Traffic light '" + signalID + "' is not a rail signal");
1825 }
1827 switch (element) {
1830 break;
1833 break;
1836 break;
1839 break;
1842 break;
1843 default:
1844 throw InvalidArgument("Unsupported rail signal constraint '" + toString((SumoXMLTag)element) + "'");
1845 }
1846 Parameterised* result = nullptr;
1847 if (ok) {
1848 for (const std::string& foe : foes) {
1849 MSRailSignalConstraint* c = new MSRailSignalConstraint_Predecessor(type, signal, foe, limit, active);
1850 rs->addConstraint(tripId, c);
1851 // XXX if there are multiple foes, only one constraint will receive the parameters
1852 result = c;
1853 }
1854 }
1855 return result;
1856}
1857
1858
1859int
1860NLHandler::parseDetectPersons(const std::string& detectPersonsString, const std::string& id, bool& ok) {
1861 int detectPersons = 0;
1862 for (std::string mode : StringTokenizer(detectPersonsString).getVector()) {
1863 if (SUMOXMLDefinitions::PersonModeValues.hasString(mode)) {
1864 detectPersons |= (int)SUMOXMLDefinitions::PersonModeValues.get(mode);
1865 } else {
1866 WRITE_ERRORF(TL("Invalid person mode '%' in E1 detector definition '%'"), mode, id);
1867 ok = false;
1868 return 0;
1869 }
1870 }
1871 return detectPersons;
1872}
1873
1874
1875/****************************************************************************/
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:57
SUMOVehicleClass getVehicleClassID(const std::string &name)
Returns the class id of the abstract class given by its name.
const SVCPermissions SVCAll
all VClasses are allowed
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_TRACTION_SUBSTATION
A traction substation.
@ SUMO_TAG_PHASE
a single phase description
@ SUMO_TAG_RAILSIGNAL_CONSTRAINTS
Constraints on switching a rail signal.
@ SUMO_TAG_BIDI_PREDECESSOR
Predecessor constraint for rail signal before bidirectional section.
@ SUMO_TAG_NET
root element of a network file
@ SUMO_TAG_REROUTER
A rerouter.
@ SUMO_TAG_INSERTION_PREDECESSOR
Predecessor constraint on insertion before rail signal.
@ SUMO_TAG_STOPOFFSET
Information on vClass specific stop offsets at lane end.
@ SUMO_TAG_WAUT_JUNCTION
@ SUMO_TAG_REQUEST
description of a logic request within the junction
@ SUMO_TAG_WAUT_SWITCH
@ SUMO_TAG_ROUTEPROBE
a routeprobe detector
@ SUMO_TAG_TAZ
a traffic assignment zone
@ SUMO_TAG_TIMEDEVENT
The definition of a periodic event.
@ SUMO_TAG_E2DETECTOR
an e2 detector
@ SUMO_TAG_CHARGING_STATION
A Charging Station.
@ SUMO_TAG_CONFLICT
conflict between two connections
@ SUMO_TAG_ACCESS
An access point for a train stop.
@ SUMO_TAG_CONDITION
a condition for phase switching
@ SUMO_TAG_CONTAINER_STOP
A container stop.
@ SUMO_TAG_TAZSINK
a sink within a district (connection road)
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_MESO
edge-specific meso settings
@ SUMO_TAG_FUNCTION
a sequence of assignments evaluated in the context of passed arguments
@ SUMO_TAG_MEANDATA_LANE
a lane based mean data detector
@ SUMO_TAG_LOCATION
@ SUMO_TAG_RESTRICTION
begin/end of the description of an edge restriction
@ SUMO_TAG_OVERHEAD_WIRE_CLAMP
An overhead wire clamp (connection of wires in opposite directions)
@ SUMO_TAG_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_MESO_TLS_FLOW_PENALTY
@ SUMO_ATTR_LATEST_END
The maximum time within the cycle for switching (for coordinated actuation)
@ SUMO_ATTR_MESO_JUNCTION_CONTROL
@ SUMO_ATTR_RED
red duration of a phase
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_VALUE
@ SUMO_ATTR_VIA
@ SUMO_ATTR_NEXT_EDGES
@ SUMO_ATTR_FILE
@ SUMO_ATTR_PROCEDURE
@ SUMO_ATTR_INDIRECT
Whether this connection is an indirect (left) turn.
@ SUMO_ATTR_Y
@ SUMO_ATTR_FROM_LANE
@ SUMO_ATTR_Z
@ SUMO_ATTR_EDGE
@ SUMO_ATTR_JAM_DIST_THRESHOLD
@ SUMO_ATTR_MESO_OVERTAKING
@ SUMO_ATTR_TRACK_VEHICLES
@ SUMO_ATTR_RESPONSE
@ SUMO_ATTR_ENDPOS
@ SUMO_ATTR_TARGETLANE
@ SUMO_ATTR_OFFSET
@ SUMO_ATTR_X
@ SUMO_ATTR_WAUT_ID
@ SUMO_ATTR_YELLOW
yellow duration of a phase
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_INTLANES
@ SUMO_ATTR_VEHICLEEXTENSION
vehicle extension time of a phase
@ SUMO_ATTR_WITH_INTERNAL
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_START_PROG
@ SUMO_ATTR_BIDI
@ SUMO_ATTR_AGGREGATE
@ SUMO_ATTR_HALTING_TIME_THRESHOLD
@ SUMO_ATTR_LIMIT
@ SUMO_ATTR_PRIORITY
@ SUMO_ATTR_MESO_TAUFF
@ SUMO_ATTR_LANES
@ SUMO_ATTR_VTYPES
@ SUMO_ATTR_SHAPE
edge: the shape in xml-definition
@ SUMO_ATTR_LEFTHAND
@ SUMO_ATTR_SIGNALS
@ SUMO_ATTR_NEXT
succesor phase index
@ SUMO_ATTR_MAX_TRAVELTIME
@ SUMO_ATTR_MESO_MINOR_PENALTY
@ SUMO_ATTR_INCLANES
@ SUMO_ATTR_CHANGE_LEFT
@ SUMO_ATTR_INDEX
@ SUMO_ATTR_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_MESO_TAUJF
@ SUMO_ATTR_SHOW_DETECTOR
@ SUMO_ATTR_FOES
@ SUMO_ATTR_FRIENDLY_POS
@ SUMO_ATTR_TO_LANE
@ SUMO_ATTR_MIN_SAMPLES
@ SUMO_ATTR_JUNCTION_ID
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_LENGTH
@ SUMO_ATTR_VERSION
@ SUMO_ATTR_COLOR
A color information.
@ SUMO_ATTR_ID
@ SUMO_ATTR_MAXDURATION
maximum duration of a phase
@ SUMO_ATTR_PROGRAMID
@ SUMO_ATTR_OUTLINESHAPE
edge: the outline shape in xml-definition
@ SUMO_ATTR_FUNCTION
@ SUMO_ATTR_MESO_TAUFJ
@ SUMO_ATTR_VISIBILITY_DISTANCE
foe visibility distance of a link
@ SUMO_ATTR_OPEN_ENTRY
@ SUMO_ATTR_MESO_TAUJJ
@ SUMO_ATTR_DURATION
@ SUMO_ATTR_WIDTH
@ SUMO_ATTR_CROSSING_EDGES
the edges crossed by a pedestrian crossing
@ SUMO_ATTR_SYNCHRON
@ SUMO_ATTR_DIR
The abstract direction of a link.
@ SUMO_ATTR_TLLINKINDEX
link: the index of the link within the traffic light
@ SUMO_ATTR_MINDURATION
@ SUMO_ATTR_CHECK
The expression for a condition assignment.
@ SUMO_ATTR_MESO_TLS_PENALTY
@ SUMO_ATTR_KEY
@ SUMO_ATTR_REF_TIME
@ SUMO_ATTR_KEEP_CLEAR
Whether vehicles must keep the junction clear.
@ SUMO_ATTR_POSITION
@ SUMO_ATTR_STATE
The state of a link.
@ SUMO_ATTR_FRICTION
@ SUMO_ATTR_TIME
trigger: the time of the step
@ SUMO_ATTR_WRITE_ATTRIBUTES
@ SUMO_ATTR_ACTIVE
@ SUMO_ATTR_DETECT_PERSONS
@ SUMO_ATTR_EXCLUDE_EMPTY
@ SUMO_ATTR_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:1355
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:1279
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:1109
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:1083
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:611
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:560
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
void addMesoType(const std::string &typeID, const MESegment::MesoEdgeType &edgeType)
Adds edge type specific meso parameters.
Definition MSNet.cpp:408
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
const MESegment::MesoEdgeType & getMesoType(const std::string &typeID)
Returns edge type specific meso parameters if no type specific parameters have been loaded,...
Definition MSNet.cpp:413
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
bool myHaveSeenMesoEdgeType
whether edge type specific meso parameters were loaded
Definition NLHandler.h:381
std::vector< Parameterised * > myLastParameterised
Definition NLHandler.h:363
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:395
void addRoundabout(const SUMOSAXAttributes &attrs)
bool myHaveSeenTLSParams
whether tls params were loaded
Definition NLHandler.h:383
void addWAUTSwitch(const SUMOSAXAttributes &attrs)
virtual void addMesoEdgeType(const SUMOSAXAttributes &attrs)
Loads edge type specific meso parameters.
bool myCurrentIsBroken
Definition NLHandler.h:358
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:378
std::string myCurrentDistrictID
The id of the current district.
Definition NLHandler.h:341
void addPhase(const SUMOSAXAttributes &attrs)
adds a phase to the traffic lights logic currently build
MMVersion myNetworkVersion
the loaded network version
Definition NLHandler.h:386
std::string myCurrentTypeID
The id of the currently processed edge type.
Definition NLHandler.h:350
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:347
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:401
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:362
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:372
NLTriggerBuilder & myTriggerBuilder
The trigger builder to use.
Definition NLHandler.h:332
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:344
JunctionGraph myJunctionGraph
Definition NLHandler.h:399
void addDistrict(const SUMOSAXAttributes &attrs)
bool myCurrentIsInternalToSkip
Information whether the currently parsed edge is internal and not wished, here.
Definition NLHandler.h:325
NLEdgeControlBuilder & myEdgeControlBuilder
The edge builder to use.
Definition NLHandler.h:335
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:366
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:89
bool myHaveSeenNeighs
whether the loaded network contains explicit neighbor lanes
Definition NLHandler.h:375
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:322
NLDetectorBuilder & myDetectorBuilder
The detector builder to use.
Definition NLHandler.h:329
void addConflict(const SUMOSAXAttributes &attrs)
NLJunctionControlBuilder & myJunctionControlBuilder
The junction builder to use.
Definition NLHandler.h:338
virtual void addE1Detector(const SUMOSAXAttributes &attrs)
Builds an e1 detector using the given specification.
virtual ~NLHandler()
Destructor.
Definition NLHandler.cpp:85
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:369
MSNet & myNet
The net to fill (preinitialised)
Definition NLHandler.h:319
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:392
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:389
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:360
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
edge type specific meso parameters
Definition MESegment.h:57