From 1e6ba8b2e2912bdfb5675bc7f7d7fc1765e7b078 Mon Sep 17 00:00:00 2001 From: Michael Behrisch Date: Tue, 14 Jan 2025 08:03:42 +0100 Subject: [PATCH] using explicit rerouter position in visualization #15426 --- src/guisim/GUITriggeredRerouter.cpp | 34 +++++++++++++------- src/guisim/GUITriggeredRerouter.h | 3 +- src/microsim/trigger/MSTriggeredRerouter.cpp | 3 ++ src/netload/NLTriggerBuilder.cpp | 25 ++++++++------ 4 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/guisim/GUITriggeredRerouter.cpp b/src/guisim/GUITriggeredRerouter.cpp index f0a4dd278ec6..5d78f220cc05 100644 --- a/src/guisim/GUITriggeredRerouter.cpp +++ b/src/guisim/GUITriggeredRerouter.cpp @@ -238,9 +238,12 @@ GUITriggeredRerouter::GUITriggeredRerouter(const std::string& id, const MSEdgeVe myShiftProbDistIndex(0) { // add visualisation objects for edges which trigger the rerouter for (MSEdgeVector::const_iterator it = edges.begin(); it != edges.end(); ++it) { - myEdgeVisualizations.push_back(new GUITriggeredRerouterEdge(dynamic_cast(*it), this, REROUTER_TRIGGER_EDGE)); + myEdgeVisualizations.push_back(new GUITriggeredRerouterEdge(dynamic_cast(*it), this, REROUTER_TRIGGER_EDGE, -1, pos, radius)); rtree.addAdditionalGLObject(myEdgeVisualizations.back()); myBoundary.add(myEdgeVisualizations.back()->getCenteringBoundary()); + if (pos != Position::INVALID) { + break; + } } } @@ -382,25 +385,32 @@ GUITriggeredRerouter::shiftProbs() { /* ------------------------------------------------------------------------- * GUITriggeredRerouterEdge - methods * ----------------------------------------------------------------------- */ -GUITriggeredRerouter::GUITriggeredRerouterEdge::GUITriggeredRerouterEdge(GUIEdge* edge, GUITriggeredRerouter* parent, RerouterEdgeType edgeType, int distIndex) : +GUITriggeredRerouter::GUITriggeredRerouterEdge::GUITriggeredRerouterEdge(GUIEdge* edge, GUITriggeredRerouter* parent, RerouterEdgeType edgeType, int distIndex, + const Position& pos, const double radius) : GUIGlObject(GLO_REROUTER_EDGE, parent->getID() + ":" + edge->getID(), GUIIconSubSys::getIcon(GUIIcon::REROUTER)), myParent(parent), myEdge(edge), myEdgeType(edgeType), myDistIndex(distIndex) { + UNUSED_PARAMETER(radius); // it would be nice to have this in the visualization too const std::vector& lanes = edge->getLanes(); - myFGPositions.reserve(lanes.size()); - myFGRotations.reserve(lanes.size()); - for (const MSLane* lane : lanes) { - if ((lane->getPermissions() & ~SVC_PEDESTRIAN) == 0) { - continue; + if (pos == Position::INVALID) { + for (const MSLane* lane : lanes) { + if ((lane->getPermissions() & ~SVC_PEDESTRIAN) == 0) { + continue; + } + const PositionVector& v = lane->getShape(); + const double lanePos = edgeType == REROUTER_TRIGGER_EDGE ? MAX2(0.0, v.length() - 6) : MIN2(v.length(), 3.0); + myFGPositions.push_back(v.positionAtOffset(lanePos)); + myFGRotations.push_back(-v.rotationDegreeAtOffset(lanePos)); + myBoundary.add(myFGPositions.back()); + myHalfWidths.push_back(lane->getWidth() * 0.5 * 0.875); } - const PositionVector& v = lane->getShape(); - const double pos = edgeType == REROUTER_TRIGGER_EDGE ? MAX2(0.0, v.length() - 6) : MIN2(v.length(), 3.0); - myFGPositions.push_back(v.positionAtOffset(pos)); - myFGRotations.push_back(-v.rotationDegreeAtOffset(pos)); + } else { + myFGPositions.push_back(pos); + myFGRotations.push_back(0); myBoundary.add(myFGPositions.back()); - myHalfWidths.push_back(lane->getWidth() * 0.5 * 0.875); + myHalfWidths.push_back(SUMO_const_halfLaneWidth * 0.875); } } diff --git a/src/guisim/GUITriggeredRerouter.h b/src/guisim/GUITriggeredRerouter.h index 0935daaa6e96..143f61015ca7 100644 --- a/src/guisim/GUITriggeredRerouter.h +++ b/src/guisim/GUITriggeredRerouter.h @@ -130,7 +130,8 @@ class GUITriggeredRerouter class GUITriggeredRerouterEdge : public GUIGlObject { public: - GUITriggeredRerouterEdge(GUIEdge* edge, GUITriggeredRerouter* parent, RerouterEdgeType edgeType, int distIndex = -1); + GUITriggeredRerouterEdge(GUIEdge* edge, GUITriggeredRerouter* parent, RerouterEdgeType edgeType, int distIndex = -1, + const Position& pos = Position::INVALID, const double radius = std::numeric_limits::max()); virtual ~GUITriggeredRerouterEdge(); diff --git a/src/microsim/trigger/MSTriggeredRerouter.cpp b/src/microsim/trigger/MSTriggeredRerouter.cpp index 6e0b2809e981..6b8a79d5a0c1 100644 --- a/src/microsim/trigger/MSTriggeredRerouter.cpp +++ b/src/microsim/trigger/MSTriggeredRerouter.cpp @@ -105,6 +105,9 @@ MSTriggeredRerouter::MSTriggeredRerouter(const std::string& id, } const std::vector vt = StringTokenizer(vTypes).getVector(); myVehicleTypes.insert(vt.begin(), vt.end()); + if (myPosition == Position::INVALID) { + myPosition = edges.front()->getLanes()[0]->getShape()[0]; + } } diff --git a/src/netload/NLTriggerBuilder.cpp b/src/netload/NLTriggerBuilder.cpp index bd36e5d1e381..85db62aee7c9 100644 --- a/src/netload/NLTriggerBuilder.cpp +++ b/src/netload/NLTriggerBuilder.cpp @@ -723,18 +723,23 @@ NLTriggerBuilder::parseAndBuildRerouter(MSNet& net, const SUMOSAXAttributes& att const bool optional = attrs.getOpt(SUMO_ATTR_OPTIONAL, id.c_str(), ok, false); const SUMOTime timeThreshold = TIME2STEPS(attrs.getOpt(SUMO_ATTR_HALTING_TIME_THRESHOLD, id.c_str(), ok, 0)); const std::string vTypes = attrs.getOpt(SUMO_ATTR_VTYPES, id.c_str(), ok, ""); - const std::string pos = attrs.getOpt(SUMO_ATTR_POSITION, id.c_str(), ok, "0"); + const std::string pos = attrs.getOpt(SUMO_ATTR_POSITION, id.c_str(), ok, ""); const double radius = attrs.getOpt(SUMO_ATTR_RADIUS, id.c_str(), ok, std::numeric_limits::max()); + if (attrs.hasAttribute(SUMO_ATTR_RADIUS) && !attrs.hasAttribute(SUMO_ATTR_POSITION)) { + WRITE_WARNINGF(TL("It is strongly advisable to give an explicit position when using radius in the definition of rerouter '%'."), id) + } Position p = Position::INVALID; - const std::vector posSplit = StringTokenizer(pos, ",").getVector(); - if (posSplit.size() == 1) { - p = edges.front()->getLanes()[0]->geometryPositionAtOffset(StringUtils::toDouble(posSplit[0])); - } else if (posSplit.size() == 2) { - p = Position(StringUtils::toDouble(posSplit[0]), StringUtils::toDouble(posSplit[1])); - } else if (posSplit.size() == 3) { - p = Position(StringUtils::toDouble(posSplit[0]), StringUtils::toDouble(posSplit[1]), StringUtils::toDouble(posSplit[2])); - } else { - throw InvalidArgument("Invalid position for rerouter '" + id + "'."); + if (pos != "") { + const std::vector posSplit = StringTokenizer(pos, ",").getVector(); + if (posSplit.size() == 1) { + p = edges.front()->getLanes()[0]->geometryPositionAtOffset(StringUtils::toDouble(pos)); + } else if (posSplit.size() == 2) { + p = Position(StringUtils::toDouble(posSplit[0]), StringUtils::toDouble(posSplit[1])); + } else if (posSplit.size() == 3) { + p = Position(StringUtils::toDouble(posSplit[0]), StringUtils::toDouble(posSplit[1]), StringUtils::toDouble(posSplit[2])); + } else { + throw InvalidArgument("Invalid position for rerouter '" + id + "'."); + } } if (!ok) { throw InvalidArgument("Could not parse rerouter '" + id + "'.");