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