コード例 #1
0
ファイル: NBEdgeCont.cpp プロジェクト: cathyyul/sumo-0.18
void
NBEdgeCont::recheckPostProcessConnections() {
    for (std::vector<PostProcessConnection>::const_iterator i = myConnections.begin(); i != myConnections.end(); ++i) {
        NBEdge* from = retrieve((*i).from);
        NBEdge* to = retrieve((*i).to);
        if (from != 0 && to != 0) {
            if (!from->addLane2LaneConnection((*i).fromLane, to, (*i).toLane, NBEdge::L2L_USER, false, (*i).mayDefinitelyPass)) {
                WRITE_WARNING("Could not insert connection between '" + (*i).from + "' and '" + (*i).to + "' after build.");
            }
        }
    }
    // during loading we also kept some ambiguous connections in hope they might be valid after processing
    // we need to make sure that all invalid connections are removed now
    for (EdgeCont::iterator it = myEdges.begin(); it != myEdges.end(); ++it) {
        NBEdge* edge = it->second;
        NBNode* to = edge->getToNode();
        // make a copy because we may delete connections
        std::vector<NBEdge::Connection> connections = edge->getConnections();
        for (std::vector<NBEdge::Connection>::iterator it_con = connections.begin(); it_con != connections.end(); ++it_con) {
            NBEdge::Connection& c = *it_con;
            if (c.toEdge != 0 && c.toEdge->getFromNode() != to) {
                WRITE_WARNING("Found and removed invalid connection from " + edge->getID() +
                              " to " + c.toEdge->getID() + " via " + to->getID());
                edge->removeFromConnections(c.toEdge);
            }
        }
    }
}
コード例 #2
0
bool
NIImporter_DlrNavteq::ProhibitionHandler::report(const std::string& result) {
// # NAME_ID    Name
    if (result[0] == '#') {
        if (myVersion == 0) {
            const double version = readVersion(result, myFile);
            if (version > 0) {
                myVersion = version;
            }
        }
        return true;
    }
    StringTokenizer st(result, StringTokenizer::TAB);
    if (st.size() == 1) {
        return true; // one line with the number of data containing lines in it (also starts with a comment # since ersion 6.5)
    }
    if (myVersion >= 6) {
        assert(st.size() >= 7);
        const std::string id = st.next();
        const std::string permanent = st.next();
        const std::string validityPeriod = st.next();
        const std::string throughTraffic = st.next();
        const std::string vehicleType = st.next();
        if (validityPeriod != UNDEFINED) {
            WRITE_WARNING("Ignoring temporary prohibited manoeuvre (" + validityPeriod + ")");
            return true;
        }
    }
    const std::string startEdge = st.next();
    const std::string endEdge = st.get(st.size() - 1);

    NBEdge* from = myEdgeCont.retrieve(startEdge);
    if (from == nullptr) {
        WRITE_WARNING("Ignoring prohibition from unknown start edge '" + startEdge + "'");
        return true;
    }
    NBEdge* to = myEdgeCont.retrieve(endEdge);
    if (to == nullptr) {
        WRITE_WARNING("Ignoring prohibition from unknown end edge '" + endEdge + "'");
        return true;
    }
    from->removeFromConnections(to, -1, -1, true);
    return true;
}
コード例 #3
0
ファイル: NBEdgeCont.cpp プロジェクト: cathyyul/sumo-0.18
void
NBEdgeCont::guessRoundabouts(std::vector<EdgeVector>& marked) {
    // step 1: keep only those edges which have no turnarounds
    std::set<NBEdge*> candidates;
    for (EdgeCont::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
        NBEdge* e = (*i).second;
        NBNode* const to = e->getToNode();
        if (e->getTurnDestination() == 0 && to->getConnectionTo(e->getFromNode()) == 0) {
            candidates.insert(e);
        }
    }

    // step 2:
    std::set<NBEdge*> visited;
    for (std::set<NBEdge*>::const_iterator i = candidates.begin(); i != candidates.end(); ++i) {
        EdgeVector loopEdges;
        // start with a random edge (this doesn't have to be a roundabout edge)
        // loop over connected edges (using always the leftmost one)
        // and keep the list in loopEdges
        // continue until we loop back onto a loopEdges and extract the loop
        NBEdge* e = (*i);
        if (visited.count(e) > 0) {
            // already seen
            continue;
        }
        loopEdges.push_back(e);
        bool doLoop = true;
        do {
            visited.insert(e);
            const EdgeVector& edges = e->getToNode()->getEdges();
            if (edges.size() < 2) {
                doLoop = false;
                break;
            }
            if (e->getTurnDestination() != 0 || e->getToNode()->getConnectionTo(e->getFromNode()) != 0) {
                // do not follow turn-arounds while in a (tentative) loop
                doLoop = false;
                break;
            }
            EdgeVector::const_iterator me = find(edges.begin(), edges.end(), e);
            NBContHelper::nextCW(edges, me);
            NBEdge* left = *me;
            SUMOReal angle = fabs(NBHelpers::relAngle(e->getAngleAtNode(e->getToNode()), left->getAngleAtNode(e->getToNode())));
            if (angle >= 90) {
                // roundabouts do not have sharp turns (or they wouldn't be called 'round')
                doLoop = false;
                break;
            }
            EdgeVector::const_iterator loopClosed = find(loopEdges.begin(), loopEdges.end(), left);
            const size_t loopSize = loopEdges.end() - loopClosed;
            if (loopSize > 0) {
                // loop found
                if (loopSize < 3) {
                    doLoop = false; // need at least 3 edges for a roundabout
                } else if (loopSize < loopEdges.size()) {
                    // remove initial edges not belonging to the loop
                    EdgeVector(loopEdges.begin() + (loopEdges.size() - loopSize), loopEdges.end()).swap(loopEdges);
                }
                // count attachments to the outside. need at least 3 or a roundabout doesn't make much sense
                int attachments = 0;
                for (EdgeVector::const_iterator j = loopEdges.begin(); j != loopEdges.end(); ++j) {
                    if ((*j)->getToNode()->getEdges().size() > 2) {
                        attachments++;
                    }
                }
                if (attachments < 3) {
                    doLoop = false;
                }
                break;
            }
            if (visited.count(left) > 0) {
                doLoop = false;
            } else {
                // keep going
                loopEdges.push_back(left);
                e = left;
            }
        } while (doLoop);
        // mark collected edges in the case a loop (roundabout) was found
        if (doLoop) {
            std::set<NBEdge*> loopEdgesSet(loopEdges.begin(), loopEdges.end());
            for (std::set<NBEdge*>::const_iterator j = loopEdgesSet.begin(); j != loopEdgesSet.end(); ++j) {
                // disable turnarounds on incoming edges
                NBNode* node = (*j)->getToNode();
                const EdgeVector& incoming = node->getIncomingEdges();
                for (EdgeVector::const_iterator k = incoming.begin(); k != incoming.end(); ++k) {
                    NBEdge* inEdge = *k;
                    if (loopEdgesSet.count(inEdge) > 0) {
                        continue;
                    }
                    if ((inEdge)->getStep() >= NBEdge::LANES2LANES_USER) {
                        continue;
                    }
                    inEdge->removeFromConnections(inEdge->getTurnDestination(), -1);
                }
                // let the connections to succeeding roundabout edge have a higher priority
                (*j)->setJunctionPriority(node, 1000);
            }
            marked.push_back(loopEdges);
        }
    }
}
コード例 #4
0
void
NIXMLConnectionsHandler::myStartElement(int element,
                                        const SUMOSAXAttributes& attrs) {
    if (element == SUMO_TAG_DELETE) {
        bool ok = true;
        std::string from = attrs.get<std::string>(SUMO_ATTR_FROM, 0, ok);
        std::string to = attrs.get<std::string>(SUMO_ATTR_TO, 0, ok);
        if (!ok) {
            return;
        }
        // these connections were removed when the edge was deleted
        if (myEdgeCont.wasRemoved(from) || myEdgeCont.wasRemoved(to)) {
            return;
        }
        NBEdge* fromEdge = myEdgeCont.retrieve(from);
        NBEdge* toEdge = myEdgeCont.retrieve(to);
        if (fromEdge == 0) {
            myErrorMsgHandler->inform("The connection-source edge '" + from + "' to reset is not known.");
            return;
        }
        if (toEdge == 0) {
            myErrorMsgHandler->inform("The connection-destination edge '" + to + "' to reset is not known.");
            return;
        }
        if (!fromEdge->isConnectedTo(toEdge) && fromEdge->getStep() >= NBEdge::EDGE2EDGES) {
            WRITE_WARNING("Target edge '" + toEdge->getID() + "' is not connected with '" + fromEdge->getID() + "'; the connection cannot be reset.");
            return;
        }
        int fromLane = -1; // Assume all lanes are to be reset.
        int toLane = -1;
        if (attrs.hasAttribute(SUMO_ATTR_LANE)
                || attrs.hasAttribute(SUMO_ATTR_FROM_LANE)
                || attrs.hasAttribute(SUMO_ATTR_TO_LANE)) {
            if (!parseLaneInfo(attrs, fromEdge, toEdge, &fromLane, &toLane)) {
                return;
            }
            // we could be trying to reset a connection loaded from a sumo net and which has become obsolete.
            // In this case it's ok to encounter invalid lance indices
            if (!fromEdge->hasConnectionTo(toEdge, toLane) && fromEdge->getStep() >= NBEdge::LANES2EDGES) {
                WRITE_WARNING("Edge '" + fromEdge->getID() + "' has no connection to lane " + toString(toLane) + " of edge '" + toEdge->getID() + "'; the connection cannot be reset.");
            }
        }
        fromEdge->removeFromConnections(toEdge, fromLane, toLane, true);
    }

    if (element == SUMO_TAG_CONNECTION) {
        bool ok = true;
        std::string from = attrs.get<std::string>(SUMO_ATTR_FROM, "connection", ok);
        std::string to = attrs.getOpt<std::string>(SUMO_ATTR_TO, "connection", ok, "");
        if (!ok || myEdgeCont.wasIgnored(from) || myEdgeCont.wasIgnored(to)) {
            return;
        }
        // extract edges
        NBEdge* fromEdge = myEdgeCont.retrieve(from);
        NBEdge* toEdge = to.length() != 0 ? myEdgeCont.retrieve(to) : 0;
        // check whether they are valid
        if (fromEdge == 0) {
            myErrorMsgHandler->inform("The connection-source edge '" + from + "' is not known.");
            return;
        }
        if (toEdge == 0 && to.length() != 0) {
            myErrorMsgHandler->inform("The connection-destination edge '" + to + "' is not known.");
            return;
        }
        fromEdge->getToNode()->invalidateTLS(myTLLogicCont, true, false);
        // parse optional lane information
        if (attrs.hasAttribute(SUMO_ATTR_LANE) || attrs.hasAttribute(SUMO_ATTR_FROM_LANE) || attrs.hasAttribute(SUMO_ATTR_TO_LANE)) {
            parseLaneBound(attrs, fromEdge, toEdge);
        } else {
            fromEdge->addEdge2EdgeConnection(toEdge);
        }
    }
    if (element == SUMO_TAG_PROHIBITION) {
        bool ok = true;
        std::string prohibitor = attrs.getOpt<std::string>(SUMO_ATTR_PROHIBITOR, 0, ok, "");
        std::string prohibited = attrs.getOpt<std::string>(SUMO_ATTR_PROHIBITED, 0, ok, "");
        if (!ok) {
            return;
        }
        NBConnection prohibitorC = parseConnection("prohibitor", prohibitor);
        NBConnection prohibitedC = parseConnection("prohibited", prohibited);
        if (prohibitorC == NBConnection::InvalidConnection || prohibitedC == NBConnection::InvalidConnection) {
            // something failed
            return;
        }
        NBNode* n = prohibitorC.getFrom()->getToNode();
        n->addSortedLinkFoes(prohibitorC, prohibitedC);
    }
    if (element == SUMO_TAG_CROSSING) {
        addCrossing(attrs);
    }
    if (element == SUMO_TAG_WALKINGAREA) {
        addWalkingArea(attrs);
    }
}