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