From c99514dc2163d15dbb0c1f739cedd9fc4433cbb7 Mon Sep 17 00:00:00 2001 From: namdre Date: Wed, 28 Mar 2018 11:10:11 +0200 Subject: [PATCH] extended duarouter output refs #3948 --- data/xsd/routeTypes.xsd | 2 ++ src/router/ROPerson.cpp | 8 ++++- src/router/ROPerson.h | 11 +++++-- src/utils/vehicle/IntermodalEdge.h | 4 +++ src/utils/vehicle/IntermodalNetwork.h | 4 +-- src/utils/vehicle/IntermodalRouter.h | 3 ++ src/utils/vehicle/PublicTransportEdge.h | 41 ++++++++++++++++++++++--- src/utils/xml/SUMOXMLDefinitions.cpp | 1 + src/utils/xml/SUMOXMLDefinitions.h | 1 + 9 files changed, 66 insertions(+), 9 deletions(-) diff --git a/data/xsd/routeTypes.xsd b/data/xsd/routeTypes.xsd index 2c3cda85df0a..d00cbb709847 100644 --- a/data/xsd/routeTypes.xsd +++ b/data/xsd/routeTypes.xsd @@ -575,6 +575,8 @@ + + diff --git a/src/router/ROPerson.cpp b/src/router/ROPerson.cpp index 6b78c9d24671..3298b74c7329 100644 --- a/src/router/ROPerson.cpp +++ b/src/router/ROPerson.cpp @@ -127,6 +127,12 @@ ROPerson::Ride::saveAsXML(OutputDevice& os, const bool extended) const { os.writeAttr(SUMO_ATTR_BUS_STOP, destStop); } os.writeAttr(SUMO_ATTR_LINES, lines); + if (intended != "") { + os.writeAttr(SUMO_ATTR_INTENDED, intended); + } + if (depart >= 0) { + os.writeAttr(SUMO_ATTR_DEPART, time2string(depart)); + } os.closeTag(); } @@ -184,7 +190,7 @@ ROPerson::computeIntermodal(const RORouterProvider& provider, PersonTrip* const veh->getRouteDefinition()->addLoadedAlternative(new RORoute(veh->getID() + "_RouteDef", it->edges)); carUsed = true; } else { - trip->addTripItem(new Ride(0, 0, it->line, it->cost, it->destStop)); + trip->addTripItem(new Ride(0, 0, it->line, it->cost, it->destStop, it->intended, TIME2STEPS(it->depart))); } } } diff --git a/src/router/ROPerson.h b/src/router/ROPerson.h index c09d5aeb2cbb..f0c2d507da6d 100644 --- a/src/router/ROPerson.h +++ b/src/router/ROPerson.h @@ -158,8 +158,13 @@ class ROPerson : public RORoutable { class Ride : public TripItem { public: Ride(const ROEdge* const _from, const ROEdge* const _to, - const std::string& _lines, const double _cost, const std::string& _destStop = "") - : TripItem(_cost), from(_from), to(_to), lines(_lines), destStop(_destStop) {} + const std::string& _lines, const double _cost, const std::string& _destStop = "", const std::string& _intended = "", const SUMOTime _depart = -1) : + TripItem(_cost), + from(_from), to(_to), + lines(_lines), + destStop(_destStop), + intended(_intended), + depart(_depart) {} const ROEdge* getOrigin() const { return from; @@ -173,6 +178,8 @@ class ROPerson : public RORoutable { const ROEdge* const from; const ROEdge* const to; const std::string lines; + const std::string intended; + const SUMOTime depart; const std::string destStop; private: diff --git a/src/utils/vehicle/IntermodalEdge.h b/src/utils/vehicle/IntermodalEdge.h index f20cdce70334..79dd6d10f869 100644 --- a/src/utils/vehicle/IntermodalEdge.h +++ b/src/utils/vehicle/IntermodalEdge.h @@ -97,6 +97,10 @@ class IntermodalEdge : public Named { return 0.; } + /// @brief set intended vehicle id and departure time of next public transport ride + virtual void setIntended(const IntermodalTrip* const /* trip */, double /* time */, std::string& intended, double& depart) const { + } + static inline double getTravelTimeStatic(const IntermodalEdge* const edge, const IntermodalTrip* const trip, double time) { return edge == nullptr ? 0. : edge->getTravelTime(trip, time); } diff --git a/src/utils/vehicle/IntermodalNetwork.h b/src/utils/vehicle/IntermodalNetwork.h index 6b64c66660ee..3d8aebf64d67 100644 --- a/src/utils/vehicle/IntermodalNetwork.h +++ b/src/utils/vehicle/IntermodalNetwork.h @@ -513,7 +513,7 @@ class IntermodalNetwork { if (lastStop != 0) { _PTEdge* const newEdge = new _PTEdge(s->busstop, myNumericalID++, lastStop, currStop->getEdge(), pars.line); addEdge(newEdge); - newEdge->addSchedule(lastTime, lastTime + pars.repetitionOffset * (pars.repetitionNumber - 1), pars.repetitionOffset, STEPS2TIME(s->until - lastTime)); + newEdge->addSchedule(pars.id, lastTime, lastTime + pars.repetitionOffset * (pars.repetitionNumber - 1), pars.repetitionOffset, STEPS2TIME(s->until - lastTime)); lastStop->addSuccessor(newEdge); newEdge->addSuccessor(currStop); lineEdges.push_back(newEdge); @@ -540,7 +540,7 @@ class IntermodalNetwork { } SUMOTime lastTime = validStops.front().until; for (lineEdge = lineEdges.begin(), s = validStops.begin() + 1; lineEdge != lineEdges.end(); ++lineEdge, ++s) { - (*lineEdge)->addSchedule(lastTime, lastTime + pars.repetitionOffset * (pars.repetitionNumber - 1), pars.repetitionOffset, STEPS2TIME(s->until - lastTime)); + (*lineEdge)->addSchedule(pars.id, lastTime, lastTime + pars.repetitionOffset * (pars.repetitionNumber - 1), pars.repetitionOffset, STEPS2TIME(s->until - lastTime)); lastTime = s->until; } } diff --git a/src/utils/vehicle/IntermodalRouter.h b/src/utils/vehicle/IntermodalRouter.h index 527b7b7971bd..5d13bacff708 100644 --- a/src/utils/vehicle/IntermodalRouter.h +++ b/src/utils/vehicle/IntermodalRouter.h @@ -69,6 +69,8 @@ class IntermodalRouter : public SUMOAbstractRouter > TripItem(const std::string& _line = "") : line(_line), cost(0.) {} std::string line; std::string destStop; + std::string intended; // intended public transport vehicle id + double depart; // intended public transport departure std::vector edges; double cost; }; @@ -124,6 +126,7 @@ class IntermodalRouter : public SUMOAbstractRouter > into.push_back(TripItem()); } else { into.push_back(TripItem(lastLine)); + iEdge->setIntended(&trip, time, into.back().intended, into.back().depart); } } if (into.back().edges.empty() || into.back().edges.back() != iEdge->getEdge()) { diff --git a/src/utils/vehicle/PublicTransportEdge.h b/src/utils/vehicle/PublicTransportEdge.h index 448177888e33..f85b6923fab5 100644 --- a/src/utils/vehicle/PublicTransportEdge.h +++ b/src/utils/vehicle/PublicTransportEdge.h @@ -38,10 +38,13 @@ template class PublicTransportEdge : public IntermodalEdge { private: struct Schedule { - Schedule(const SUMOTime _begin, const SUMOTime _end, const SUMOTime _period, const double _travelTimeSec) - : begin(STEPS2TIME(_begin)), end(STEPS2TIME(_end)), period(STEPS2TIME(_period)), travelTimeSec(_travelTimeSec) {} + Schedule(const std::string& _id, const SUMOTime _begin, const SUMOTime _end, const SUMOTime _period, const double _travelTimeSec) + : id(_id), begin(STEPS2TIME(_begin)), end(STEPS2TIME(_end)), period(STEPS2TIME(_period)), travelTimeSec(_travelTimeSec) {} + // the id of the vehicle or flow from which this schedule is generated + const std::string id; const double begin; const double end; + // the repetition period for a flow or -1 for a vehicle const double period; const double travelTimeSec; private: @@ -65,11 +68,11 @@ class PublicTransportEdge : public IntermodalEdge { return myEntryStop; } - void addSchedule(const SUMOTime begin, const SUMOTime end, const SUMOTime period, const double travelTimeSec) { + void addSchedule(const std::string id, const SUMOTime begin, const SUMOTime end, const SUMOTime period, const double travelTimeSec) { //std::cout << " edge=" << myEntryStop->getID() << "->" << this->getID() << " beg=" << STEPS2TIME(begin) << " end=" << STEPS2TIME(end) // << " period=" << STEPS2TIME(period) // << " travelTime=" << travelTimeSec << "\n"; - mySchedules.insert(std::make_pair(STEPS2TIME(begin), Schedule(begin, end, period, travelTimeSec))); + mySchedules.insert(std::make_pair(STEPS2TIME(begin), Schedule(id, begin, end, period, travelTimeSec))); } double getTravelTime(const IntermodalTrip* const /* trip */, double time) const { @@ -99,6 +102,36 @@ class PublicTransportEdge : public IntermodalEdge { return minArrivalSec - time; } + void setIntended(const IntermodalTrip* const /* trip */, double time, std::string& intended, double& depart) const { + /// @note: duplicates some code of getTravelTime() + double minArrivalSec = std::numeric_limits::max(); + double bestDepartTime = std::numeric_limits::max(); + for (typename std::multimap::const_iterator it = mySchedules.begin(); it != mySchedules.end(); ++it) { + const Schedule& s = it->second; + if (it->first > minArrivalSec) { + break; + } + if (time < s.end) { + int running; + if (s.period <= 0 || time < s.begin) { + // single vehicle or flow begin + running = 0; + } else { + // subsequent flow + running = (int)ceil((time - s.begin) / s.period); + } + const double nextDepart = s.begin + running * s.period; + if (nextDepart + s.travelTimeSec < minArrivalSec) { + minArrivalSec = nextDepart + s.travelTimeSec; + bestDepartTime = nextDepart; + // see naming scheme inMSInsertionControl::determineCandidates() + intended = s.period <= 0 ? s.id : s.id + "." + toString(running); + } + } + } + depart = bestDepartTime; + } + private: std::multimap mySchedules; const IntermodalEdge* const myEntryStop; diff --git a/src/utils/xml/SUMOXMLDefinitions.cpp b/src/utils/xml/SUMOXMLDefinitions.cpp index 576b7c2ec8b5..0cf7294c3ef2 100644 --- a/src/utils/xml/SUMOXMLDefinitions.cpp +++ b/src/utils/xml/SUMOXMLDefinitions.cpp @@ -447,6 +447,7 @@ StringBijection::Entry SUMOXMLDefinitions::attrs[] = { { "chargingStation", SUMO_ATTR_CHARGING_STATION}, { "line", SUMO_ATTR_LINE }, { "lines", SUMO_ATTR_LINES }, + { "intended", SUMO_ATTR_INTENDED }, { "value", SUMO_ATTR_VALUE }, { "prohibitor", SUMO_ATTR_PROHIBITOR }, { "prohibited", SUMO_ATTR_PROHIBITED }, diff --git a/src/utils/xml/SUMOXMLDefinitions.h b/src/utils/xml/SUMOXMLDefinitions.h index 1d8c1f3af6b4..8829dd02e258 100644 --- a/src/utils/xml/SUMOXMLDefinitions.h +++ b/src/utils/xml/SUMOXMLDefinitions.h @@ -677,6 +677,7 @@ enum SumoXMLAttr { SUMO_ATTR_CHARGING_STATION, SUMO_ATTR_LINE, SUMO_ATTR_LINES, + SUMO_ATTR_INTENDED, SUMO_ATTR_VALUE, SUMO_ATTR_PROHIBITOR, SUMO_ATTR_PROHIBITED,