Exemplo n.º 1
0
bool
ROJTRRouter::compute(const ROEdge* from, const ROEdge* to,
                     const ROVehicle* const vehicle,
                     SUMOTime time, ConstROEdgeVector& into) {
    const ROJTREdge* current = static_cast<const ROJTREdge*>(from);
    SUMOReal timeS = STEPS2TIME(time);
    std::set<const ROEdge*> avoidEdges;
    // route until a sinks has been found
    while (current != 0 && current != to &&
            current->getFunc() != ROEdge::ET_SINK &&
            (int)into.size() < myMaxEdges) {
        into.push_back(current);
        if (!myAllowLoops) {
            avoidEdges.insert(current);
        }
        timeS += current->getTravelTime(vehicle, timeS);
        current = current->chooseNext(myIgnoreClasses ? 0 : vehicle, timeS, avoidEdges);
        assert(myIgnoreClasses || current == 0 || !current->prohibits(vehicle));
    }
    // check whether no valid ending edge was found
    if (current == 0 || (int) into.size() >= myMaxEdges) {
        if (myAcceptAllDestination) {
            return true;
        } else {
            MsgHandler* mh = myUnbuildIsWarningOnly ? MsgHandler::getWarningInstance() : MsgHandler::getErrorInstance();
            mh->inform("The route starting at edge '" + from->getID() + "' could not be closed.");
            return false;
        }
    }
    // append the sink
    if (current != 0) {
        into.push_back(current);
    }
    return true;
}
Exemplo n.º 2
0
SUMOReal
ROJTRRouter::recomputeCosts(const ConstROEdgeVector& edges, const ROVehicle* const v, SUMOTime time) const {
    SUMOReal costs = 0;
    for (ConstROEdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
        costs += (*i)->getTravelTime(v, time);
    }
    return costs;
}
Exemplo n.º 3
0
RORouteDef*
RORouteDef::copyOrigDest(const std::string& id) const {
    RORouteDef* result = new RORouteDef(id, 0, true, true);
    RORoute* route = myAlternatives[0];
    RGBColor* col = route->getColor() != 0 ? new RGBColor(*route->getColor()) : 0;
    ConstROEdgeVector edges;
    edges.push_back(route->getFirst());
    edges.push_back(route->getLast());
    result->addLoadedAlternative(new RORoute(id, 0, 1, edges, col, route->getStops()));
    return result;
}
Exemplo n.º 4
0
void
RORouteHandler::parseFromViaTo(std::string element,
                               const SUMOSAXAttributes& attrs) {
    myActiveRoute.clear();
    bool useTaz = OptionsCont::getOptions().getBool("with-taz");
    if (useTaz && !myVehicleParameter->wasSet(VEHPARS_FROM_TAZ_SET) && !myVehicleParameter->wasSet(VEHPARS_TO_TAZ_SET)) {
        WRITE_WARNING("Taz usage was requested but no taz present in " + element + " '" + myVehicleParameter->id + "'!");
        useTaz = false;
    }
    bool ok = true;
    if ((useTaz || !attrs.hasAttribute(SUMO_ATTR_FROM)) && myVehicleParameter->wasSet(VEHPARS_FROM_TAZ_SET)) {
        const ROEdge* fromTaz = myNet.getEdge(myVehicleParameter->fromTaz + "-source");
        if (fromTaz == 0) {
            myErrorOutput->inform("Source taz '" + myVehicleParameter->fromTaz + "' not known for " + element + " '" + myVehicleParameter->id + "'!");
        } else if (fromTaz->getNumSuccessors() == 0) {
            myErrorOutput->inform("Source taz '" + myVehicleParameter->fromTaz + "' has no outgoing edges for " + element + " '" + myVehicleParameter->id + "'!");
        } else {
            myActiveRoute.push_back(fromTaz);
        }
    } else {
        parseEdges(attrs.getOpt<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok, "", true),
                   myActiveRoute, "for " + element + " '" + myVehicleParameter->id + "'");
    }
    if (!attrs.hasAttribute(SUMO_ATTR_VIA)) {
        myInsertStopEdgesAt = (int)myActiveRoute.size();
    }
    ConstROEdgeVector viaEdges;
    parseEdges(attrs.getOpt<std::string>(SUMO_ATTR_VIA, myVehicleParameter->id.c_str(), ok, "", true),
               viaEdges, "for " + element + " '" + myVehicleParameter->id + "'");
    for (ConstROEdgeVector::const_iterator i = viaEdges.begin(); i != viaEdges.end(); ++i) {
        myActiveRoute.push_back(*i);
        myVehicleParameter->via.push_back((*i)->getID());
    }

    if ((useTaz || !attrs.hasAttribute(SUMO_ATTR_TO)) && myVehicleParameter->wasSet(VEHPARS_TO_TAZ_SET)) {
        const ROEdge* toTaz = myNet.getEdge(myVehicleParameter->toTaz + "-sink");
        if (toTaz == 0) {
            myErrorOutput->inform("Sink taz '" + myVehicleParameter->toTaz + "' not known for " + element + " '" + myVehicleParameter->id + "'!");
        } else if (toTaz->getNumPredecessors() == 0) {
            myErrorOutput->inform("Sink taz '" + myVehicleParameter->toTaz + "' has no incoming edges for " + element + " '" + myVehicleParameter->id + "'!");
        } else {
            myActiveRoute.push_back(toTaz);
        }
    } else {
        parseEdges(attrs.getOpt<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok, "", true),
                   myActiveRoute, "for " + element + " '" + myVehicleParameter->id + "'");
    }
    myActiveRouteID = "!" + myVehicleParameter->id;
    if (myVehicleParameter->routeid == "") {
        myVehicleParameter->routeid = myActiveRouteID;
    }
}
Exemplo n.º 5
0
void
ROVehicle::addStop(const SUMOVehicleParameter::Stop& stopPar, const RONet* net, MsgHandler* errorHandler) {
    const ROEdge* stopEdge = net->getEdgeForLaneID(stopPar.lane);
    assert(stopEdge != 0); // was checked when parsing the stop
    if (stopEdge->prohibits(this)) {
        if (errorHandler != nullptr) {
            errorHandler->inform("Stop edge '" + stopEdge->getID() + "' does not allow vehicle '" + getID() + "'.");
        }
        return;
    }
    // where to insert the stop
    std::vector<SUMOVehicleParameter::Stop>::iterator iter = getParameter().stops.begin();
    ConstROEdgeVector::iterator edgeIter = myStopEdges.begin();
    if (stopPar.index == STOP_INDEX_END || stopPar.index >= static_cast<int>(getParameter().stops.size())) {
        if (getParameter().stops.size() > 0) {
            iter = getParameter().stops.end();
            edgeIter = myStopEdges.end();
        }
    } else {
        if (stopPar.index == STOP_INDEX_FIT) {
            const ConstROEdgeVector edges = myRoute->getFirstRoute()->getEdgeVector();
            ConstROEdgeVector::const_iterator stopEdgeIt = std::find(edges.begin(), edges.end(), stopEdge);
            if (stopEdgeIt == edges.end()) {
                iter = getParameter().stops.end();
                edgeIter = myStopEdges.end();
            } else {
                while (iter != getParameter().stops.end()) {
                    if (edgeIter > stopEdgeIt || (edgeIter == stopEdgeIt && iter->endPos >= stopPar.endPos)) {
                        break;
                    }
                    ++iter;
                    ++edgeIter;
                }
            }
        } else {
            iter += stopPar.index;
            edgeIter += stopPar.index;
        }
    }
    getParameter().stops.insert(iter, stopPar);
    myStopEdges.insert(edgeIter, stopEdge);
}
Exemplo n.º 6
0
OutputDevice&
RORoute::writeXMLDefinition(OutputDevice& dev, const ROVehicle* const veh,
                            const bool withCosts,
                            const bool withExitTimes) const {
    dev.openTag(SUMO_TAG_ROUTE);
    if (withCosts) {
        dev.writeAttr(SUMO_ATTR_COST, myCosts);
        dev.setPrecision(8);
        dev.writeAttr(SUMO_ATTR_PROB, myProbability);
        dev.setPrecision();
    }
    if (myColor != 0) {
        dev.writeAttr(SUMO_ATTR_COLOR, *myColor);
    }
    ConstROEdgeVector tempRoute;
    for (const ROEdge* roe : myRoute) {
        if (!roe->isInternal() && !roe->isTazConnector()) {
            tempRoute.push_back(roe);
        }
    }
    dev.writeAttr(SUMO_ATTR_EDGES, tempRoute);
    if (withExitTimes) {
        std::vector<double> exitTimes;
        double time = STEPS2TIME(veh->getDepartureTime());
        bool addSep = false;
        for (const ROEdge* roe : myRoute) {
            time += roe->getTravelTime(veh, time);
            if (!roe->isInternal() && !roe->isTazConnector()) {
                exitTimes.push_back(time);
            }
        }
        dev.writeAttr("exitTimes", exitTimes);
    }
    dev.closeTag();
    return dev;
}
Exemplo n.º 7
0
void
RORouteHandler::closeRoute(const bool mayBeDisconnected) {
    if (myActiveRoute.size() == 0) {
        if (myActiveRouteRefID != "" && myCurrentAlternatives != 0) {
            myCurrentAlternatives->addAlternativeDef(myNet.getRouteDef(myActiveRouteRefID));
            myActiveRouteID = "";
            myActiveRouteRefID = "";
            return;
        }
        if (myVehicleParameter != 0) {
            myErrorOutput->inform("The route for vehicle '" + myVehicleParameter->id + "' has no edges.");
        } else {
            myErrorOutput->inform("Route '" + myActiveRouteID + "' has no edges.");
        }
        myActiveRouteID = "";
        myActiveRouteStops.clear();
        return;
    }
    if (myActiveRoute.size() == 1 && myActiveRoute.front()->isTazConnector()) {
        myErrorOutput->inform("The routing information for vehicle '" + myVehicleParameter->id + "' is insufficient.");
        myActiveRouteID = "";
        myActiveRouteStops.clear();
        return;
    }
    if (!mayBeDisconnected && OptionsCont::getOptions().exists("no-internal-links") && !OptionsCont::getOptions().getBool("no-internal-links")) {
        // fix internal edges which did not get parsed
        const ROEdge* last = nullptr;
        ConstROEdgeVector fullRoute;
        for (const ROEdge* roe : myActiveRoute) {
            if (last != nullptr) {
                for (const ROEdge* intern : last->getSuccessors()) {
                    if (intern->isInternal() && intern->getSuccessors().size() == 1 && intern->getSuccessors().front() == roe) {
                        fullRoute.push_back(intern);
                    }
                }
            }
            fullRoute.push_back(roe);
            last = roe;
        }
        myActiveRoute = fullRoute;
    }
    RORoute* route = new RORoute(myActiveRouteID, myCurrentCosts, myActiveRouteProbability, myActiveRoute,
                                 myActiveRouteColor, myActiveRouteStops);
    myActiveRoute.clear();
    if (myCurrentAlternatives == 0) {
        if (myNet.getRouteDef(myActiveRouteID) != 0) {
            delete route;
            if (myVehicleParameter != 0) {
                myErrorOutput->inform("Another route for vehicle '" + myVehicleParameter->id + "' exists.");
            } else {
                myErrorOutput->inform("Another route (or distribution) with the id '" + myActiveRouteID + "' exists.");
            }
            myActiveRouteID = "";
            myActiveRouteStops.clear();
            return;
        } else {
            myCurrentAlternatives = new RORouteDef(myActiveRouteID, 0, mayBeDisconnected || myTryRepair, mayBeDisconnected);
            myCurrentAlternatives->addLoadedAlternative(route);
            myNet.addRouteDef(myCurrentAlternatives);
            myCurrentAlternatives = 0;
        }
    } else {
        myCurrentAlternatives->addLoadedAlternative(route);
    }
    myActiveRouteID = "";
    myActiveRouteStops.clear();
}
Exemplo n.º 8
0
void
RORouteDef::preComputeCurrentRoute(SUMOAbstractRouter<ROEdge, ROVehicle>& router,
                                   SUMOTime begin, const ROVehicle& veh) const {
    myNewRoute = false;
    const OptionsCont& oc = OptionsCont::getOptions();
    assert(myAlternatives[0]->getEdgeVector().size() > 0);
    MsgHandler* mh = (OptionsCont::getOptions().getBool("ignore-errors") ?
                      MsgHandler::getWarningInstance() : MsgHandler::getErrorInstance());
    if (myAlternatives[0]->getFirst()->prohibits(&veh) && (!oc.getBool("repair.from")
            // do not try to reassign starting edge for trip input
            || myMayBeDisconnected || myAlternatives[0]->getEdgeVector().size() < 2)) {
        mh->inform("Vehicle '" + veh.getID() + "' is not allowed to depart on edge '" +
                   myAlternatives[0]->getFirst()->getID() + "'.");
        return;
    } else if (myAlternatives[0]->getLast()->prohibits(&veh) && (!oc.getBool("repair.to")
               // do not try to reassign destination edge for trip input
               || myMayBeDisconnected || myAlternatives[0]->getEdgeVector().size() < 2)) {
        // this check is not strictly necessary unless myTryRepair is set.
        // However, the error message is more helpful than "no connection found"
        mh->inform("Vehicle '" + veh.getID() + "' is not allowed to arrive on edge '" +
                   myAlternatives[0]->getLast()->getID() + "'.");
        return;
    }
    if (myTryRepair || myUsingJTRR) {
        ConstROEdgeVector newEdges;
        if (repairCurrentRoute(router, begin, veh, myAlternatives[0]->getEdgeVector(), newEdges)) {
            if (myAlternatives[0]->getEdgeVector() != newEdges) {
                if (!myMayBeDisconnected) {
                    WRITE_WARNING("Repaired route of vehicle '" + veh.getID() + "'.");
                }
                myNewRoute = true;
                RGBColor* col = myAlternatives[0]->getColor() != 0 ? new RGBColor(*myAlternatives[0]->getColor()) : 0;
                myPrecomputed = new RORoute(myID, 0, myAlternatives[0]->getProbability(), newEdges, col, myAlternatives[0]->getStops());
            } else {
                myPrecomputed = myAlternatives[0];
            }
        }
        return;
    }
    if (RouteCostCalculator<RORoute, ROEdge, ROVehicle>::getCalculator().skipRouteCalculation()
            || OptionsCont::getOptions().getBool("remove-loops")) {
        myPrecomputed = myAlternatives[myLastUsed];
    } else {
        // build a new route to test whether it is better
        ConstROEdgeVector oldEdges;
        oldEdges.push_back(myAlternatives[0]->getFirst());
        oldEdges.push_back(myAlternatives[0]->getLast());
        ConstROEdgeVector edges;
        repairCurrentRoute(router, begin, veh, oldEdges, edges);
        // check whether the same route was already used
        int cheapest = -1;
        for (int i = 0; i < (int)myAlternatives.size(); i++) {
            if (edges == myAlternatives[i]->getEdgeVector()) {
                cheapest = i;
                break;
            }
        }
        if (cheapest >= 0) {
            myPrecomputed = myAlternatives[cheapest];
        } else {
            RGBColor* col = myAlternatives[0]->getColor() != 0 ? new RGBColor(*myAlternatives[0]->getColor()) : 0;
            myPrecomputed = new RORoute(myID, 0, 1, edges, col, myAlternatives[0]->getStops());
            myNewRoute = true;
        }
    }
}
Exemplo n.º 9
0
bool
RORouteDef::repairCurrentRoute(SUMOAbstractRouter<ROEdge, ROVehicle>& router,
                               SUMOTime begin, const ROVehicle& veh,
                               ConstROEdgeVector oldEdges, ConstROEdgeVector& newEdges) const {
    MsgHandler* mh = (OptionsCont::getOptions().getBool("ignore-errors") ?
                      MsgHandler::getWarningInstance() : MsgHandler::getErrorInstance());
    const int initialSize = (int)oldEdges.size();
    if (initialSize == 1) {
        if (myUsingJTRR) {
            /// only ROJTRRouter is supposed to handle this type of input
            router.compute(oldEdges.front(), 0, &veh, begin, newEdges);
        } else {
            newEdges = oldEdges;
        }
    } else {
        if (oldEdges.front()->prohibits(&veh)) {
            // option repair.from is in effect
            const std::string& frontID = oldEdges.front()->getID();
            for (ConstROEdgeVector::iterator i = oldEdges.begin(); i != oldEdges.end();) {
                if ((*i)->prohibits(&veh) || (*i)->isInternal()) {
                    i = oldEdges.erase(i);
                } else {
                    WRITE_MESSAGE("Changing invalid starting edge '" + frontID
                                  + "' to '" + (*i)->getID() + "' for vehicle '" + veh.getID() + "'.");
                    break;
                }
            }
        }
        if (oldEdges.size() == 0) {
            mh->inform("Could not find new starting edge for vehicle '" + veh.getID() + "'.");
            return false;
        }
        if (oldEdges.back()->prohibits(&veh)) {
            // option repair.to is in effect
            const std::string& backID = oldEdges.back()->getID();
            // oldEdges cannot get empty here, otherwise we would have left the stage when checking "from"
            while (oldEdges.back()->prohibits(&veh) || oldEdges.back()->isInternal()) {
                oldEdges.pop_back();
            }
            WRITE_MESSAGE("Changing invalid destination edge '" + backID
                          + "' to edge '" + oldEdges.back()->getID() + "' for vehicle '" + veh.getID() + "'.");
        }
        ConstROEdgeVector mandatory = veh.getMandatoryEdges(oldEdges.front(), oldEdges.back());
        assert(mandatory.size() >= 2);
        // removed prohibited
        for (ConstROEdgeVector::iterator i = oldEdges.begin(); i != oldEdges.end();) {
            if ((*i)->prohibits(&veh) || (*i)->isInternal()) {
                // no need to check the mandatories here, this was done before
                i = oldEdges.erase(i);
            } else {
                ++i;
            }
        }
        // reconnect remaining edges
        if (mandatory.size() > oldEdges.size() && initialSize > 2) {
            WRITE_MESSAGE("There are stop edges which were not part of the original route for vehicle '" + veh.getID() + "'.");
        }
        const ConstROEdgeVector& targets = mandatory.size() > oldEdges.size() ? mandatory : oldEdges;
        newEdges.push_back(*(targets.begin()));
        ConstROEdgeVector::iterator nextMandatory = mandatory.begin() + 1;
        int lastMandatory = 0;
        for (ConstROEdgeVector::const_iterator i = targets.begin() + 1;
                i != targets.end() && nextMandatory != mandatory.end(); ++i) {
            if ((*(i - 1))->isConnectedTo(*i, &veh)) {
                newEdges.push_back(*i);
            } else {
                if (initialSize > 2) {
                    // only inform if the input is (probably) not a trip
                    WRITE_MESSAGE("Edge '" + (*(i - 1))->getID() + "' not connected to edge '" + (*i)->getID() + "' for vehicle '" + veh.getID() + "'.");
                }
                const ROEdge* const last = newEdges.back();
                newEdges.pop_back();
                if (!router.compute(last, *i, &veh, begin, newEdges)) {
                    // backtrack: try to route from last mandatory edge to next mandatory edge
                    // XXX add option for backtracking in smaller increments
                    // (i.e. previous edge to edge after *i)
                    // we would then need to decide whether we have found a good
                    // tradeoff between faithfulness to the input data and detour-length
                    ConstROEdgeVector edges;
                    if (lastMandatory >= (int)newEdges.size() || last == newEdges[lastMandatory] || !router.compute(newEdges[lastMandatory], *nextMandatory, &veh, begin, edges)) {
                        mh->inform("Mandatory edge '" + (*i)->getID() + "' not reachable by vehicle '" + veh.getID() + "'.");
                        return false;
                    }
                    while (*i != *nextMandatory) {
                        ++i;
                    }
                    newEdges.erase(newEdges.begin() + lastMandatory + 1, newEdges.end());
                    std::copy(edges.begin() + 1, edges.end(), back_inserter(newEdges));
                }
            }
            if (*i == *nextMandatory) {
                nextMandatory++;
                lastMandatory = (int)newEdges.size() - 1;
            }
        }
    }
    return true;
}
Exemplo n.º 10
0
void
ROVehicle::saveAsXML(OutputDevice& os, OutputDevice* const typeos, bool asAlternatives, OptionsCont& options) const {
    if (typeos != nullptr && getType() != nullptr && !getType()->saved) {
        getType()->write(*typeos);
        getType()->saved = true;
    }
    if (getType() != nullptr && !getType()->saved) {
        getType()->write(os);
        getType()->saved = asAlternatives;
    }

    const bool writeTrip = options.exists("write-trips") && options.getBool("write-trips");
    const bool writeGeoTrip = writeTrip && options.getBool("write-trips.geo");
    // write the vehicle (new style, with included routes)
    getParameter().write(os, options, writeTrip ? SUMO_TAG_TRIP : SUMO_TAG_VEHICLE);

    // save the route
    if (writeTrip) {
        const ConstROEdgeVector edges = myRoute->getFirstRoute()->getEdgeVector();
        const ROEdge* from = nullptr;
        const ROEdge* to = nullptr;
        if (edges.size() > 0) {
            if (edges.front()->isTazConnector()) {
                if (edges.size() > 1) {
                    from = edges[1];
                }
            } else {
                from = edges[0];
            }
            if (edges.back()->isTazConnector()) {
                if (edges.size() > 1) {
                    to = edges[edges.size() - 2];
                }
            } else {
                to = edges[edges.size() - 1];
            }
        }
        if (from != nullptr) {
            if (writeGeoTrip) {
                Position fromPos = from->getLanes()[0]->getShape().positionAtOffset2D(0);
                if (GeoConvHelper::getFinal().usingGeoProjection()) {
                    os.setPrecision(gPrecisionGeo);
                    GeoConvHelper::getFinal().cartesian2geo(fromPos);
                    os.writeAttr(SUMO_ATTR_FROMLONLAT, fromPos);
                    os.setPrecision(gPrecision);
                } else {
                    os.writeAttr(SUMO_ATTR_FROMXY, fromPos);
                }
            } else {
                os.writeAttr(SUMO_ATTR_FROM, from->getID());
            }
        }
        if (to != nullptr) {
            if (writeGeoTrip) {
                Position toPos = to->getLanes()[0]->getShape().positionAtOffset2D(to->getLanes()[0]->getShape().length2D());
                if (GeoConvHelper::getFinal().usingGeoProjection()) {
                    os.setPrecision(gPrecisionGeo);
                    GeoConvHelper::getFinal().cartesian2geo(toPos);
                    os.writeAttr(SUMO_ATTR_TOLONLAT, toPos);
                    os.setPrecision(gPrecision);
                } else {
                    os.writeAttr(SUMO_ATTR_TOXY, toPos);
                }
            } else {
                os.writeAttr(SUMO_ATTR_TO, to->getID());
            }
        }
        if (getParameter().via.size() > 0) {
            if (writeGeoTrip) {
                PositionVector viaPositions;
                for (const std::string& viaID : getParameter().via) {
                    const ROEdge* viaEdge = RONet::getInstance()->getEdge(viaID);
                    assert(viaEdge != nullptr);
                    Position viaPos = viaEdge->getLanes()[0]->getShape().positionAtOffset2D(viaEdge->getLanes()[0]->getShape().length2D() / 2);
                    viaPositions.push_back(viaPos);
                }
                if (GeoConvHelper::getFinal().usingGeoProjection()) {
                    for (int i = 0; i < (int)viaPositions.size(); i++) {
                        GeoConvHelper::getFinal().cartesian2geo(viaPositions[i]);
                    }
                    os.setPrecision(gPrecisionGeo);
                    os.writeAttr(SUMO_ATTR_VIALONLAT, viaPositions);
                    os.setPrecision(gPrecision);
                } else {
                    os.writeAttr(SUMO_ATTR_VIAXY, viaPositions);
                }

            } else {
                os.writeAttr(SUMO_ATTR_VIA, getParameter().via);
            }
        }
    } else {
        myRoute->writeXMLDefinition(os, this, asAlternatives, options.getBool("exit-times"));
    }
    for (std::vector<SUMOVehicleParameter::Stop>::const_iterator stop = getParameter().stops.begin(); stop != getParameter().stops.end(); ++stop) {
        stop->write(os);
    }
    getParameter().writeParams(os);
    os.closeTag();
}
Exemplo n.º 11
0
ConstROEdgeVector
ROVehicle::getMandatoryEdges(const ROEdge* requiredStart, const ROEdge* requiredEnd) const {
    ConstROEdgeVector mandatory;
    if (requiredStart) {
        mandatory.push_back(requiredStart);
    }
    for (const ROEdge* e : getStopEdges()) {
        if (e->isInternal()) {
            // the edges before and after the internal edge are mandatory
            const ROEdge* before = e->getNormalBefore();
            const ROEdge* after = e->getNormalAfter();
            if (mandatory.size() == 0 || after != mandatory.back()) {
                mandatory.push_back(before);
                mandatory.push_back(after);
            }
        } else {
            if (mandatory.size() == 0 || e != mandatory.back()) {
                mandatory.push_back(e);
            }
        }
    }
    if (requiredEnd) {
        if (mandatory.size() < 2 || mandatory.back() != requiredEnd) {
            mandatory.push_back(requiredEnd);
        }
    }
    return mandatory;
}
Exemplo n.º 12
0
void
RODFNet::computeRoutesFor(ROEdge* edge, RODFRouteDesc& base, int /*no*/,
                          bool keepUnfoundEnds,
                          bool keepShortestOnly,
                          ROEdgeVector& /*visited*/,
                          const RODFDetector& det, RODFRouteCont& into,
                          const RODFDetectorCon& detectors,
                          int maxFollowingLength,
                          ROEdgeVector& seen) const {
    std::vector<RODFRouteDesc> unfoundEnds;
    std::priority_queue<RODFRouteDesc, std::vector<RODFRouteDesc>, DFRouteDescByTimeComperator> toSolve;
    std::map<ROEdge*, ROEdgeVector > dets2Follow;
    dets2Follow[edge] = ROEdgeVector();
    base.passedNo = 0;
    SUMOReal minDist = OptionsCont::getOptions().getFloat("min-route-length");
    toSolve.push(base);
    while (!toSolve.empty()) {
        RODFRouteDesc current = toSolve.top();
        toSolve.pop();
        ROEdge* last = *(current.edges2Pass.end() - 1);
        if (hasDetector(last)) {
            if (dets2Follow.find(last) == dets2Follow.end()) {
                dets2Follow[last] = ROEdgeVector();
            }
            for (ROEdgeVector::reverse_iterator i = current.edges2Pass.rbegin() + 1; i != current.edges2Pass.rend(); ++i) {
                if (hasDetector(*i)) {
                    dets2Follow[*i].push_back(last);
                    break;
                }
            }
        }

        // do not process an edge twice
        if (find(seen.begin(), seen.end(), last) != seen.end() && keepShortestOnly) {
            continue;
        }
        seen.push_back(last);
        // end if the edge has no further connections
        if (!hasApproached(last)) {
            // ok, no further connections to follow
            current.factor = 1.;
            SUMOReal cdist = current.edges2Pass[0]->getFromJunction()->getPosition().distanceTo(current.edges2Pass.back()->getToJunction()->getPosition());
            if (minDist < cdist) {
                into.addRouteDesc(current);
            }
            continue;
        }
        // check for passing detectors:
        //  if the current last edge is not the one the detector is placed on ...
        bool addNextNoFurther = false;
        if (last != getDetectorEdge(det)) {
            // ... if there is a detector ...
            if (hasDetector(last)) {
                if (!hasInBetweenDetectorsOnly(last, detectors)) {
                    // ... and it's not an in-between-detector
                    // -> let's add this edge and the following, but not any further
                    addNextNoFurther = true;
                    current.lastDetectorEdge = last;
                    current.duration2Last = (SUMOTime) current.duration_2;
                    current.distance2Last = current.distance;
                    current.endDetectorEdge = last;
                    if (hasSourceDetector(last, detectors)) {
///!!!                        //toDiscard.push_back(current);
                    }
                    current.factor = 1.;
                    SUMOReal cdist = current.edges2Pass[0]->getFromJunction()->getPosition().distanceTo(current.edges2Pass.back()->getToJunction()->getPosition());
                    if (minDist < cdist) {
                        into.addRouteDesc(current);
                    }
                    continue;
                } else {
                    // ... if it's an in-between-detector
                    // -> mark the current route as to be continued
                    current.passedNo = 0;
                    current.duration2Last = (SUMOTime) current.duration_2;
                    current.distance2Last = current.distance;
                    current.lastDetectorEdge = last;
                }
            }
        }
        // check for highway off-ramps
        if (myAmInHighwayMode) {
            // if it's beside the highway...
            if (last->getSpeed() < 19.4 && last != getDetectorEdge(det)) {
                // ... and has more than one following edge
                if (myApproachedEdges.find(last)->second.size() > 1) {
                    // -> let's add this edge and the following, but not any further
                    addNextNoFurther = true;
                }

            }
        }
        // check for missing end connections
        if (!addNextNoFurther) {
            // ... if this one would be processed, but already too many edge
            //  without a detector occured
            if (current.passedNo > maxFollowingLength) {
                // mark not to process any further
                WRITE_WARNING("Could not close route for '" + det.getID() + "'");
                unfoundEnds.push_back(current);
                current.factor = 1.;
                SUMOReal cdist = current.edges2Pass[0]->getFromJunction()->getPosition().distanceTo(current.edges2Pass.back()->getToJunction()->getPosition());
                if (minDist < cdist) {
                    into.addRouteDesc(current);
                }
                continue;
            }
        }
        // ... else: loop over the next edges
        const ROEdgeVector& appr  = myApproachedEdges.find(last)->second;
        bool hadOne = false;
        for (size_t i = 0; i < appr.size(); i++) {
            if (find(current.edges2Pass.begin(), current.edges2Pass.end(), appr[i]) != current.edges2Pass.end()) {
                // do not append an edge twice (do not build loops)
                continue;
            }
            RODFRouteDesc t(current);
            t.duration_2 += (appr[i]->getLength() / appr[i]->getSpeed()); //!!!
            t.distance += appr[i]->getLength();
            t.edges2Pass.push_back(appr[i]);
            if (!addNextNoFurther) {
                t.passedNo = t.passedNo + 1;
                toSolve.push(t);
            } else {
                if (!hadOne) {
                    t.factor = (SUMOReal) 1. / (SUMOReal) appr.size();
                    SUMOReal cdist = current.edges2Pass[0]->getFromJunction()->getPosition().distanceTo(current.edges2Pass.back()->getToJunction()->getPosition());
                    if (minDist < cdist) {
                        into.addRouteDesc(t);
                    }
                    hadOne = true;
                }
            }
        }
    }
    //
    if (!keepUnfoundEnds) {
        std::vector<RODFRouteDesc>::iterator i;
        ConstROEdgeVector lastDetEdges;
        for (i = unfoundEnds.begin(); i != unfoundEnds.end(); ++i) {
            if (find(lastDetEdges.begin(), lastDetEdges.end(), (*i).lastDetectorEdge) == lastDetEdges.end()) {
                lastDetEdges.push_back((*i).lastDetectorEdge);
            } else {
                bool ok = into.removeRouteDesc(*i);
                assert(ok);
                UNUSED_PARAMETER(ok); // ony used for assertion
            }
        }
    } else {
        // !!! patch the factors
    }
    while (!toSolve.empty()) {
//        RODFRouteDesc d = toSolve.top();
        toSolve.pop();
//        delete d;
    }
}