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
IntermodalRouter< E, L, N, V > & getIntermodalRouter() const
const EdgePair & getBothDirections(const E *e) const
Returns the pair of forward and backward edge.
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
int repetitionNumber
The number of times the vehicle shall be repeatedly inserted.
_IntermodalEdge * getDepartConnector(const E *e, const int splitIndex=0) const
Returns the departing intermodal connector at the given split offset.
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.
const std::string & getID() const
Returns the id.
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)
_IntermodalEdge * getCarEdge(const E *e) const
Returns the associated car edge.
std::vector< Stop > stops
List of the stops the vehicle will make, TraCI may add entries here.
const E * getEdge() const
_IntermodalEdge * getWalkingConnector(const E *e) const
Returns the outgoing pedestrian edge, which is either a walking area or a walking connector...
std::string busstop
(Optional) bus stop if one is assigned to the stop
PublicTransportEdge< E, L, N, V > _PTEdge
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...
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 setSuccessors(const std::vector< IntermodalEdge *> &edges)
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)
PedestrianRouterDijkstra< E, L, N, V > & getPedestrianRouter() const
std::vector< std::string > & split(const std::string &s, char delim, std::vector< std::string > &elems)
std::vector< const E * > edges
IntermodalRouter(CreateNetCallback callback, int carWalkTransfer)
Constructor.
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
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
SUMOAbstractRouter< E, V > & getVehicleRouter() const
_IntermodalEdge * getDepartEdge(const E *e, const double pos) const
Returns the departing intermodal edge.
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
void prohibit(const std::vector< E *> &toProhibit)
IntermodalRouter< E, L, N, V > *const myInterRouter
Static storage of an output device and its base (abstract) implementation.
bool closeTag()
Closes the most recently opened tag.
double recomputeCosts(const std::vector< const E *> &, const _IntermodalTrip *const, SUMOTime) const
the pedestrian edge type that is given to the internal router (SUMOAbstractRouter) ...
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
void addCarEdges(const std::vector< E *> &edges)
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)