20 #ifndef IntermodalRouter_h 21 #define IntermodalRouter_h 58 template<
class E,
class L,
class N,
class V,
class INTERNALROUTER = DijkstraRouter<IntermodalEdge<E, L, N, V>, IntermodalTrip<E, N, V>, prohibited_withPermissions<IntermodalEdge<E, L, N, V>, IntermodalTrip<E, N, V> > > >
125 void addAccess(
const std::string& stopId,
const E* stopEdge,
const double pos,
const SumoXMLTag category) {
126 assert(stopEdge != 0);
132 const L* lane = getSidewalk<E, L>(stopEdge);
136 const int splitIndex =
splitEdge(pair.first, fwdSplit, pos, stopConn);
139 _IntermodalEdge* carSplit =
nullptr;
144 if (splitIndex >= 0) {
147 for (_IntermodalEdge* conn : {
150 _AccessEdge* access =
new _AccessEdge(myNumericalID++, beforeSplit, conn);
158 const std::vector<_IntermodalEdge*>& backSplitList =
myAccessSplits[pair.second];
159 _IntermodalEdge*
const backBeforeSplit = backSplitList[backSplitList.size() - 1 - splitIndex];
161 _IntermodalEdge*
const depConn =
new _IntermodalEdge(stopEdge->
getID() +
"_depart_connector" +
toString(pos), myNumericalID++, stopEdge,
"!connector");
168 if (carSplit !=
nullptr) {
173 _IntermodalEdge*
const fwdBeforeSplit =
myAccessSplits[pair.first][splitIndex - 1];
174 _IntermodalEdge*
const arrConn =
new _IntermodalEdge(stopEdge->getID() +
"_arrival_connector" +
toString(pos), myNumericalID++, stopEdge,
"!connector");
181 if (carSplit !=
nullptr) {
197 std::vector<SUMOVehicleParameter::Stop> validStops;
200 for (std::vector<SUMOVehicleParameter::Stop>::const_iterator s = addStops->begin(); s != addStops->end(); ++s) {
205 if (stop.
until >= lastUntil) {
206 validStops.push_back(stop);
207 lastUntil = stop.
until;
214 for (std::vector<SUMOVehicleParameter::Stop>::const_iterator s = pars.
stops.begin(); s != pars.
stops.end(); ++s) {
217 validStops.push_back(*s);
218 lastUntil = s->until;
221 if (validStops.size() < 2) {
222 WRITE_WARNING(
"Ignoring public transport line '" + pars.
line +
"' with less than two usable stops.");
226 typename std::vector<_PTEdge*>& lineEdges =
myPTLines[pars.
line];
227 if (lineEdges.empty()) {
228 _IntermodalEdge* lastStop = 0;
230 for (std::vector<SUMOVehicleParameter::Stop>::const_iterator s = validStops.begin(); s != validStops.end(); ++s) {
238 lineEdges.push_back(newEdge);
244 if (validStops.size() != lineEdges.size() + 1) {
245 WRITE_WARNING(
"Number of stops for public transport line '" + pars.
line +
"' does not match earlier definitions, ignoring schedule.");
248 if (lineEdges.front()->getEntryStop() !=
myStopConnections[validStops.front().busstop]) {
249 WRITE_WARNING(
"Different stop for '" + pars.
line +
"' compared to earlier definitions, ignoring schedule.");
252 typename std::vector<_PTEdge*>::const_iterator lineEdge = lineEdges.begin();
253 typename std::vector<SUMOVehicleParameter::Stop>::const_iterator s = validStops.begin() + 1;
254 for (; s != validStops.end(); ++s, ++lineEdge) {
256 WRITE_WARNING(
"Different stop for '" + pars.
line +
"' compared to earlier definitions, ignoring schedule.");
260 SUMOTime lastTime = validStops.front().until;
261 for (lineEdge = lineEdges.begin(), s = validStops.begin() + 1; lineEdge != lineEdges.end(); ++lineEdge, ++s) {
270 bool compute(
const E* from,
const E* to,
double departPos,
double arrivalPos,
double speed,
272 std::vector<TripItem>& into) {
274 _IntermodalTrip trip(from, to, departPos, arrivalPos, speed, msTime, 0, vehicle, modeSet);
275 std::vector<const _IntermodalEdge*> intoEdges;
278 &trip, msTime, intoEdges);
280 std::string lastLine =
"";
282 for (
const _IntermodalEdge* iEdge : intoEdges) {
283 if (iEdge->includeInRoute(
false)) {
284 if (iEdge->getLine() ==
"!stop") {
285 into.back().destStop = iEdge->getID();
286 if (lastLine ==
"!ped") {
290 if (iEdge->getLine() != lastLine) {
291 lastLine = iEdge->getLine();
292 if (lastLine ==
"!car") {
293 into.push_back(
TripItem(vehicle->getID()));
294 }
else if (lastLine ==
"!ped") {
300 if (into.back().edges.empty() || into.back().edges.back() != iEdge->getEdge()) {
301 into.back().edges.push_back(iEdge->getEdge());
308 into.back().cost += edgeEffort;
312 #ifdef IntermodalRouter_DEBUG_ROUTES 314 for (
const _IntermodalEdge* iEdge : intoEdges) {
317 std::cout << iEdge->getID() <<
"(" << iEdge->getLine() <<
"): " << edgeEffort << std::endl;
319 std::cout <<
TIME2STEPS(msTime) <<
" trip from " << from->getID() <<
" to " << to->getID()
332 bool compute(
const E*,
const E*,
const _IntermodalTrip*
const,
343 std::vector<_IntermodalEdge*> toProhibitPE;
344 for (
typename std::vector<E*>::const_iterator it = toProhibit.begin(); it != toProhibit.end(); ++it) {
359 for (_IntermodalEdge* suc : e->getSuccessors(
SVC_IGNORING)) {
360 succStr += suc->getID() +
" ";
381 myInternalRouter(new INTERNALROUTER(net->getAllEdges(), true, &_IntermodalEdge::getTravelTimeStatic)),
397 int splitEdge(_IntermodalEdge*
const toSplit, _IntermodalEdge* afterSplit,
const double pos,
398 _IntermodalEdge*
const stopConn,
const bool forward =
true,
const bool addExit =
true) {
399 std::vector<_IntermodalEdge*>& splitList =
myAccessSplits[toSplit];
400 if (splitList.empty()) {
401 splitList.push_back(toSplit);
405 for (
const _IntermodalEdge*
const split : splitList) {
409 relPos -=
split->getLength();
412 assert(splitIndex < (
int)splitList.size());
413 _IntermodalEdge* beforeSplit = splitList[splitIndex];
414 if (splitIndex + 1 < (
int)splitList.size() && fabs(relPos - beforeSplit->getLength()) <
POSITION_EPS) {
416 afterSplit = splitList[splitIndex + 1];
421 beforeSplit->clearSuccessors();
422 beforeSplit->addSuccessor(afterSplit);
423 afterSplit->
setLength(beforeSplit->getLength() - relPos);
424 beforeSplit->setLength(relPos);
427 const std::string newID = beforeSplit->getID();
428 beforeSplit->setID(afterSplit->
getID());
429 afterSplit->
setID(newID);
432 splitList.insert(splitList.begin() + splitIndex, afterSplit);
437 beforeSplit->addSuccessor(access);
450 for (
const E*
const edge : edges) {
457 _IntermodalEdge*
const carEdge = edgePair.second;
458 for (
const E*
const suc : edgePair.first->getSuccessors()) {
459 _IntermodalEdge*
const sucCarEdge =
getCarEdge(suc);
460 if (sucCarEdge !=
nullptr) {
470 for (
const E*
const out : edgePair.first->getToJunction()->getOutgoing()) {
471 if (!out->isInternal() && !out->isTazConnector() && getSidewalk<E, L>(out) != 0) {
475 for (
const E*
const in : edgePair.first->getToJunction()->getIncoming()) {
476 if (!in->isInternal() && !in->isTazConnector() && getSidewalk<E, L>(in) != 0) {
499 typename std::map<const E*, _IntermodalEdge*>::const_iterator it =
myCarLookup.find(e);
518 std::map<std::string, std::vector<_PTEdge*> >
myPTLines;
539 template<
class E,
class L,
class N,
class V>
545 : myVehRouter(vehRouter), myPedRouter(pedRouter), myInterRouter(interRouter) {}
548 : myVehRouter(original.getVehicleRouter().
clone()),
550 myInterRouter(static_cast<
IntermodalRouter<E, L, N, V>*>(original.myInterRouter == 0 ? 0 : original.getIntermodalRouter().
clone())) {}
561 return *myInterRouter;
567 delete myInterRouter;
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
ModeChangeOptions
where mode changes are possible
SumoXMLTag
Numbers representing SUMO-XML - element names.
IntermodalRouter & operator=(const IntermodalRouter &s)
Invalidated assignment operator.
_IntermodalEdge * getArrivalEdge(const E *e, const double pos) const
Returns the arriving intermodal edge.
std::map< const E *, _IntermodalEdge * > myCarLookup
retrieve the car edge for the given input edge E
_IntermodalEdge * getDepartEdge(const E *e, const double pos) const
Returns the departing intermodal edge.
int repetitionNumber
The number of times the vehicle shall be repeatedly inserted.
const std::vector< _IntermodalEdge * > & getAllEdges()
RouterProvider(const RouterProvider &original)
virtual ~RouterProvider()
SUMOAbstractRouter< E, V > *const myVehRouter
void addEdge(_IntermodalEdge *edge)
void(* CreateNetCallback)(IntermodalRouter< E, L, N, V, INTERNALROUTER > &)
static double getTravelTimeStatic(const IntermodalEdge *const edge, const IntermodalTrip< E, N, V > *const trip, double time)
AccessEdge< E, L, N, V > _AccessEdge
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
int splitEdge(_IntermodalEdge *const toSplit, _IntermodalEdge *afterSplit, const double pos, _IntermodalEdge *const stopConn, const bool forward=true, const bool addExit=true)
Splits an edge (if necessary) and connects it to a stopping edge.
void addSuccessor(IntermodalEdge *s)
_IntermodalNetwork * myIntermodalNet
std::string time2string(SUMOTime t)
std::map< _IntermodalEdge *, std::vector< _IntermodalEdge * > > myAccessSplits
retrieve the splitted edges for the given "original"
the car edge type that is given to the internal router (SUMOAbstractRouter)
void writeNetwork(OutputDevice &dev)
const int myCarWalkTransfer
void addSchedule(const SUMOTime begin, const SUMOTime end, const SUMOTime period, const double travelTimeSec)
std::map< std::string, std::vector< _PTEdge * > > myPTLines
retrieve the public transport edges for the given line
SUMOTime until
The time at which the vehicle may continue its journey.
bool compute(const E *, const E *, const _IntermodalTrip *const, SUMOTime, std::vector< const E * > &)
Builds the route between the given edges using the minimum effort at the given time The definition of...
void writeWeights(OutputDevice &dev)
TripItem(const std::string &_line="")
#define WRITE_WARNING(msg)
SUMOTime repetitionOffset
The time offset between vehicle reinsertions.
void removeSuccessor(const IntermodalEdge *const edge)
PedestrianRouterDijkstra< E, L, N, V > & getPedestrianRouter() const
std::vector< Stop > stops
List of the stops the vehicle will make, TraCI may add entries here.
std::string busstop
(Optional) bus stop if one is assigned to the stop
PublicTransportEdge< E, L, N, V > _PTEdge
const std::string & getID() const
Returns the id.
bool compute(const E *from, const E *to, double departPos, double arrivalPos, double speed, const V *const vehicle, const SVCPermissions modeSet, SUMOTime msTime, std::vector< TripItem > &into)
Builds the route between the given edges using the minimum effort at the given time The definition of...
CreateNetCallback myCallback
void addSchedule(const SUMOVehicleParameter &pars, const std::vector< SUMOVehicleParameter::Stop > *addStops=0)
void addAccess(const std::string &stopId, const E *stopEdge, const double pos, const SumoXMLTag category)
Adds access edges for stopping places to the intermodal network.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
IntermodalRouter(_IntermodalNetwork *net)
void prohibit(const std::vector< E * > &toProhibit)
IntermodalTrip< E, N, V > _IntermodalTrip
SUMOAbstractRouter< E, _IntermodalTrip > * clone()
_IntermodalEdge * getArrivalConnector(const E *e, const int splitIndex=0) const
Returns the arriving intermodal connector at the given split offset.
SUMOTime depart
The vehicle's departure time.
the "vehicle" type that is given to the internal router (SUMOAbstractRouter)
std::vector< std::string > & split(const std::string &s, char delim, std::vector< std::string > &elems)
SUMOAbstractRouter< E, V > & getVehicleRouter() const
std::vector< const E * > edges
double recomputeCosts(const std::vector< const E * > &, const _IntermodalTrip *const, SUMOTime) const
_IntermodalEdge * getCarEdge(const E *e) const
Returns the associated car edge.
IntermodalRouter(CreateNetCallback callback, int carWalkTransfer)
Constructor.
const E * getEdge() const
PedestrianRouterDijkstra< E, L, N, V > *const myPedRouter
the intermodal network storing edges, connections and the mappings to the "real" edges ...
public transport stops and access
const EdgePair & getBothDirections(const E *e) const
Returns the pair of forward and backward edge.
std::string line
The vehicle's line (mainly for public transport)
begin/end of the description of an edge
the base edge type that is given to the internal router (SUMOAbstractRouter)
INTERNALROUTER * myInternalRouter
std::map< std::string, _IntermodalEdge * > myStopConnections
retrieve the connecting edges for the given "bus" stop
IntermodalNetwork< E, L, N, V > _IntermodalNetwork
void setID(const std::string &newID)
resets the id
Structure representing possible vehicle parameter.
IntermodalEdge< E, L, N, V > _IntermodalEdge
virtual ~IntermodalRouter()
Destructor.
Definition of vehicle stop (position and duration)
the public transport edge type connecting the stop edges
IntermodalRouter< E, L, N, V > *const myInterRouter
IntermodalRouter< E, L, N, V > & getIntermodalRouter() const
_IntermodalEdge * getDepartConnector(const E *e, const int splitIndex=0) const
Returns the departing intermodal connector at the given split offset.
Static storage of an output device and its base (abstract) implementation.
bool closeTag()
Closes the most recently opened tag.
the pedestrian edge type that is given to the internal router (SUMOAbstractRouter) ...
_IntermodalEdge * getWalkingConnector(const E *e) const
Returns the outgoing pedestrian edge, which is either a walking area or a walking connector...
void setSuccessors(const std::vector< IntermodalEdge * > &edges)
void addCarEdges(const std::vector< E * > &edges)
RouterProvider(SUMOAbstractRouter< E, V > *vehRouter, PedestrianRouterDijkstra< E, L, N, V > *pedRouter, IntermodalRouter< E, L, N, V > *interRouter)
void addConnectors(_IntermodalEdge *const depConn, _IntermodalEdge *const arrConn, const int splitIndex)
the stop edge type representing bus and train stops
junctions with edges allowing the additional mode
vehicles ignoring classes
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
the access edge connecting different modes that is given to the internal router (SUMOAbstractRouter) ...
std::string id
The vehicle's id.
void setLength(const double length)