コード例 #1
0
NBEdge*
NIImporter_VISUM::getNamedEdgeContinuating(NBEdge* begin, NBNode* node) {
    if (begin == 0) {
        return 0;
    }
    NBEdge* ret = begin;
    std::string edgeID = ret->getID();
    // hangle forward
    while (ret != 0) {
        // ok, this is the edge we are looking for
        if (ret->getToNode() == node) {
            return ret;
        }
        const EdgeVector& nedges = ret->getToNode()->getOutgoingEdges();
        if (nedges.size() != 1) {
            // too many edges follow
            ret = 0;
            continue;
        }
        NBEdge* next = nedges[0];
        if (ret->getID().substr(0, edgeID.length()) != next->getID().substr(0, edgeID.length())) {
            // ok, another edge is next...
            ret = 0;
            continue;
        }
        if (next->getID().substr(next->getID().length() - node->getID().length()) != node->getID()) {
            ret = 0;
            continue;
        }
        ret = next;
    }

    ret = begin;
    // hangle backward
    while (ret != 0) {
        // ok, this is the edge we are looking for
        if (ret->getFromNode() == node) {
            return ret;
        }
        const EdgeVector& nedges = ret->getFromNode()->getIncomingEdges();
        if (nedges.size() != 1) {
            // too many edges follow
            ret = 0;
            continue;
        }
        NBEdge* next = nedges[0];
        if (ret->getID().substr(0, edgeID.length()) != next->getID().substr(0, edgeID.length())) {
            // ok, another edge is next...
            ret = 0;
            continue;
        }
        if (next->getID().substr(next->getID().length() - node->getID().length()) != node->getID()) {
            ret = 0;
            continue;
        }
        ret = next;
    }
    return 0;
}
コード例 #2
0
ファイル: NWWriter_SUMO.cpp プロジェクト: aarongolliver/sumo
void
NWWriter_SUMO::writeEdge(OutputDevice& into, const NBEdge& e, bool noNames, bool origNames) {
    // write the edge's begin
    into.openTag(SUMO_TAG_EDGE).writeAttr(SUMO_ATTR_ID, e.getID());
    into.writeAttr(SUMO_ATTR_FROM, e.getFromNode()->getID());
    into.writeAttr(SUMO_ATTR_TO, e.getToNode()->getID());
    if (!noNames && e.getStreetName() != "") {
        into.writeAttr(SUMO_ATTR_NAME, StringUtils::escapeXML(e.getStreetName()));
    }
    into.writeAttr(SUMO_ATTR_PRIORITY, e.getPriority());
    if (e.getTypeID() != "") {
        into.writeAttr(SUMO_ATTR_TYPE, e.getTypeID());
    }
    if (e.isMacroscopicConnector()) {
        into.writeAttr(SUMO_ATTR_FUNCTION, EDGEFUNC_CONNECTOR);
    }
    // write the spread type if not default ("right")
    if (e.getLaneSpreadFunction() != LANESPREAD_RIGHT) {
        into.writeAttr(SUMO_ATTR_SPREADTYPE, e.getLaneSpreadFunction());
    }
    if (e.hasLoadedLength()) {
        into.writeAttr(SUMO_ATTR_LENGTH, e.getLoadedLength());
    }
    if (!e.hasDefaultGeometry()) {
        into.writeAttr(SUMO_ATTR_SHAPE, e.getGeometry());
    }
    // write the lanes
    const std::vector<NBEdge::Lane>& lanes = e.getLanes();

    SUMOReal length = e.getLoadedLength();
    if (OptionsCont::getOptions().getBool("no-internal-links") && !e.hasLoadedLength()) {
        // use length to junction center even if a modified geometry was given
        PositionVector geom = e.cutAtIntersection(e.getGeometry());
        geom.push_back_noDoublePos(e.getToNode()->getCenter());
        geom.push_front_noDoublePos(e.getFromNode()->getCenter());
        length = geom.length();
    }
    if (length <= 0) {
        length = POSITION_EPS;
    }
    for (unsigned int i = 0; i < (unsigned int) lanes.size(); i++) {
        const NBEdge::Lane& l = lanes[i];
        writeLane(into, e.getID(), e.getLaneID(i), l.speed,
                  l.permissions, l.preferred, l.endOffset, l.width, l.shape, l.origID,
                  length, i, origNames);
    }
    // close the edge
    into.closeTag();
}
コード例 #3
0
// ===========================================================================
// method definitions
// ===========================================================================
// ---------------------------------------------------------------------------
// NBRampsComputer
// ---------------------------------------------------------------------------
void
NBRampsComputer::computeRamps(NBNetBuilder& nb, OptionsCont& oc) {
    SUMOReal minHighwaySpeed = oc.getFloat("ramps.min-highway-speed");
    SUMOReal maxRampSpeed = oc.getFloat("ramps.max-ramp-speed");
    SUMOReal rampLength = oc.getFloat("ramps.ramp-length");
    bool dontSplit = oc.getBool("ramps.no-split");
    std::set<NBEdge*> incremented;
    // check whether on-off ramps shall be guessed
    if (oc.getBool("ramps.guess")) {
        NBNodeCont& nc = nb.getNodeCont();
        NBEdgeCont& ec = nb.getEdgeCont();
        NBDistrictCont& dc = nb.getDistrictCont();
        std::set<NBNode*> potOnRamps;
        std::set<NBNode*> potOffRamps;
        for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
            NBNode* cur = (*i).second;
            if (mayNeedOnRamp(cur, minHighwaySpeed, maxRampSpeed)) {
                potOnRamps.insert(cur);
            }
            if (mayNeedOffRamp(cur, minHighwaySpeed, maxRampSpeed)) {
                potOffRamps.insert(cur);
            }
        }
        for (std::set<NBNode*>::const_iterator i = potOnRamps.begin(); i != potOnRamps.end(); ++i) {
            buildOnRamp(*i, nc, ec, dc, rampLength, dontSplit, incremented);
        }
        for (std::set<NBNode*>::const_iterator i = potOffRamps.begin(); i != potOffRamps.end(); ++i) {
            buildOffRamp(*i, nc, ec, dc, rampLength, dontSplit, incremented);
        }
    }
    // check whether on-off ramps shall be guessed
    if (oc.isSet("ramps.set")) {
        std::vector<std::string> edges = oc.getStringVector("ramps.set");
        NBNodeCont& nc = nb.getNodeCont();
        NBEdgeCont& ec = nb.getEdgeCont();
        NBDistrictCont& dc = nb.getDistrictCont();
        for (std::vector<std::string>::iterator i = edges.begin(); i != edges.end(); ++i) {
            NBEdge* e = ec.retrieve(*i);
            if (e == 0) {
                WRITE_WARNING("Can not build on ramp on edge '" + *i + "' - the edge is not known.");
                continue;
            }
            NBNode* from = e->getFromNode();
            if (from->getIncomingEdges().size() == 2 && from->getOutgoingEdges().size() == 1) {
                buildOnRamp(from, nc, ec, dc, rampLength, dontSplit, incremented);
            }
            // load edge again to check offramps
            e = ec.retrieve(*i);
            if (e == 0) {
                WRITE_WARNING("Can not build off ramp on edge '" + *i + "' - the edge is not known.");
                continue;
            }
            NBNode* to = e->getToNode();
            if (to->getIncomingEdges().size() == 1 && to->getOutgoingEdges().size() == 2) {
                buildOffRamp(to, nc, ec, dc, rampLength, dontSplit, incremented);
            }
        }
    }
}
コード例 #4
0
void
NWWriter_DlrNavteq::writeLinksUnsplitted(const OptionsCont& oc, NBEdgeCont& ec) {
    std::map<const std::string, std::string> nameIDs;
    OutputDevice& device = OutputDevice::getDevice(oc.getString("dlr-navteq-output") + "_links_unsplitted.txt");
    writeHeader(device, oc);
    // write format specifier
    device << "# LINK_ID\tNODE_ID_FROM\tNODE_ID_TO\tBETWEEN_NODE_ID\tLENGTH\tVEHICLE_TYPE\tFORM_OF_WAY\tBRUNNEL_TYPE\tFUNCTIONAL_ROAD_CLASS\tSPEED_CATEGORY\tNUMBER_OF_LANES\tSPEED_LIMIT\tSPEED_RESTRICTION\tNAME_ID1_REGIONAL\tNAME_ID2_LOCAL\tHOUSENUMBERS_RIGHT\tHOUSENUMBERS_LEFT\tZIP_CODE\tAREA_ID\tSUBAREA_ID\tTHROUGH_TRAFFIC\tSPECIAL_RESTRICTIONS\tEXTENDED_NUMBER_OF_LANES\tISRAMP\tCONNECTION\n";
    // write edges
    for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) {
        NBEdge* e = (*i).second;
        const int kph = speedInKph(e->getSpeed());
        const std::string& betweenNodeID = (e->getGeometry().size() > 2) ? e->getID() : UNDEFINED;
        std::string nameID = UNDEFINED;
        if (oc.getBool("output.street-names")) {
            const std::string& name = i->second->getStreetName();
            if (name != "" && nameIDs.count(name) == 0) {
                nameID = toString(nameIDs.size());
                nameIDs[name] = nameID;
            }
        }
        device << e->getID() << "\t"
               << e->getFromNode()->getID() << "\t"
               << e->getToNode()->getID() << "\t"
               << betweenNodeID << "\t"
               << getGraphLength(e) << "\t"
               << getAllowedTypes(e->getPermissions()) << "\t"
               << "3\t" // Speed Category 1-8 XXX refine this
               << UNDEFINED << "\t" // no special brunnel type (we don't know yet)
               << getRoadClass(e) << "\t"
               << getSpeedCategory(kph) << "\t"
               << getNavteqLaneCode(e->getNumLanes()) << "\t"
               << getSpeedCategoryUpperBound(kph) << "\t"
               << kph << "\t"
               << nameID << "\t" // NAME_ID1_REGIONAL XXX
               << UNDEFINED << "\t" // NAME_ID2_LOCAL XXX
               << UNDEFINED << "\t" // housenumbers_right
               << UNDEFINED << "\t" // housenumbers_left
               << UNDEFINED << "\t" // ZIP_CODE
               << UNDEFINED << "\t" // AREA_ID
               << UNDEFINED << "\t" // SUBAREA_ID
               << "1\t" // through_traffic (allowed)
               << UNDEFINED << "\t" // special_restrictions
               << UNDEFINED << "\t" // extended_number_of_lanes
               << UNDEFINED << "\t" // isRamp
               << "0\t" // connection (between nodes always in order)
               << "\n";
    }
    if (oc.getBool("output.street-names")) {
        OutputDevice& namesDevice = OutputDevice::getDevice(oc.getString("dlr-navteq-output") + "_names.txt");
        writeHeader(namesDevice, oc);
        // write format specifier
        namesDevice << "# NAME_ID\tName\n" << nameIDs.size() << "\n";
        for (std::map<const std::string, std::string>::const_iterator i = nameIDs.begin(); i != nameIDs.end(); ++i) {
            namesDevice << i->second << "\t" << i->first << "\n";
        }
    }
}
コード例 #5
0
void
NIXMLConnectionsHandler::addWalkingArea(const SUMOSAXAttributes& attrs) {
    bool ok = true;
    NBNode* node = 0;
    EdgeVector edges;
    const std::string nodeID = attrs.get<std::string>(SUMO_ATTR_NODE, 0, ok);
    std::vector<std::string> edgeIDs;
    if (!attrs.hasAttribute(SUMO_ATTR_EDGES)) {
        WRITE_ERROR("No edges specified for walkingArea at node '" + nodeID + "'.");
        return;
    }
    SUMOSAXAttributes::parseStringVector(attrs.get<std::string>(SUMO_ATTR_EDGES, 0, ok), edgeIDs);
    if (!ok) {
        return;
    }
    for (std::vector<std::string>::const_iterator it = edgeIDs.begin(); it != edgeIDs.end(); ++it) {
        NBEdge* edge = myEdgeCont.retrieve(*it);
        if (edge == 0) {
            WRITE_ERROR("Edge '" + (*it) + "' for walkingArea at node '" + nodeID + "' is not known.");
            return;
        }
        if (node == 0) {
            if (edge->getToNode()->getID() == nodeID) {
                node = edge->getToNode();
            } else if (edge->getFromNode()->getID() == nodeID) {
                node = edge->getFromNode();
            } else {
                WRITE_ERROR("Edge '" + (*it) + "' does not touch node '" + nodeID + "'.");
                return;
            }
        } else {
            if (edge->getToNode() != node && edge->getFromNode() != node) {
                WRITE_ERROR("Edge '" + (*it) + "' does not touch node '" + nodeID + "'.");
                return;
            }
        }
        edges.push_back(edge);
    }
    PositionVector customShape = attrs.getOpt<PositionVector>(SUMO_ATTR_SHAPE, 0, ok, PositionVector::EMPTY);
    if (!NBNetBuilder::transformCoordinates(customShape)) {
        WRITE_ERROR("Unable to project shape for walkingArea at node '" + node->getID() + "'.");
    }
    node->addWalkingAreaShape(edges, customShape);
}
コード例 #6
0
ファイル: GNENet.cpp プロジェクト: cbrafter/sumo
void
GNENet::insertEdge(GNEEdge* edge) {
    NBEdge* nbe = edge->getNBEdge();
    myNetBuilder->getEdgeCont().insert(nbe); // should we ignore pruning double edges?
    // if this edge was previouls extracted from the edgeContainer we have to
    // rewire the nodes
    nbe->getFromNode()->addOutgoingEdge(nbe);
    nbe->getToNode()->addIncomingEdge(nbe);
    // Add references to this edge in additionalSets
    for(std::vector<GNEAdditionalSet*>::const_iterator i = edge->getAdditionalSets().begin(); i != edge->getAdditionalSets().end(); i++) {
        (*i)->addEdgeChild(edge);
    }
    registerEdge(edge);
}
コード例 #7
0
ファイル: NBEdgeCont.cpp プロジェクト: cathyyul/sumo-0.18
// ----- Adapting the input
void
NBEdgeCont::removeUnwishedEdges(NBDistrictCont& dc) {
    EdgeVector toRemove;
    for (EdgeCont::iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
        NBEdge* edge = (*i).second;
        if (!myEdges2Keep.count(edge->getID())) {
            edge->getFromNode()->removeEdge(edge);
            edge->getToNode()->removeEdge(edge);
            toRemove.push_back(edge);
        }
    }
    for (EdgeVector::iterator j = toRemove.begin(); j != toRemove.end(); ++j) {
        erase(dc, *j);
    }
}
コード例 #8
0
// ----------- (Helper) methods for joining nodes
void
NBNodeCont::generateNodeClusters(SUMOReal maxDist, NodeClusters& into) const {
    std::set<NBNode*> visited;
    for (NodeCont::const_iterator i = myNodes.begin(); i != myNodes.end(); i++) {
        std::vector<NBNode*> toProc;
        if (visited.find((*i).second) != visited.end()) {
            continue;
        }
        toProc.push_back((*i).second);
        std::set<NBNode*> c;
        while (!toProc.empty()) {
            NBNode* n = toProc.back();
            toProc.pop_back();
            if (visited.find(n) != visited.end()) {
                continue;
            }
            c.insert(n);
            visited.insert(n);
            const EdgeVector& edges = n->getEdges();
            for (EdgeVector::const_iterator j = edges.begin(); j != edges.end(); ++j) {
                NBEdge* e = *j;
                NBNode* s = 0;
                if (n->hasIncoming(e)) {
                    s = e->getFromNode();
                } else {
                    s = e->getToNode();
                }
                if (visited.find(s) != visited.end()) {
                    continue;
                }
                if (e->getLoadedLength() < maxDist) {
                    toProc.push_back(s);
                }
            }
        }
        if (c.size() < 2) {
            continue;
        }
        into.push_back(c);
    }
}
コード例 #9
0
void
NWWriter_SUMO::writeEdge(OutputDevice& into, const NBEdge& e, bool noNames, bool origNames) {
    // write the edge's begin
    into.openTag(SUMO_TAG_EDGE).writeAttr(SUMO_ATTR_ID, e.getID());
    into.writeAttr(SUMO_ATTR_FROM, e.getFromNode()->getID());
    into.writeAttr(SUMO_ATTR_TO, e.getToNode()->getID());
    if (!noNames && e.getStreetName() != "") {
        into.writeAttr(SUMO_ATTR_NAME, StringUtils::escapeXML(e.getStreetName()));
    }
    into.writeAttr(SUMO_ATTR_PRIORITY, e.getPriority());
    if (e.getTypeName() != "") {
        into.writeAttr(SUMO_ATTR_TYPE, e.getTypeName());
    }
    if (e.isMacroscopicConnector()) {
        into.writeAttr(SUMO_ATTR_FUNCTION, EDGEFUNC_CONNECTOR);
    }
    // write the spread type if not default ("right")
    if (e.getLaneSpreadFunction() != LANESPREAD_RIGHT) {
        into.writeAttr(SUMO_ATTR_SPREADTYPE, e.getLaneSpreadFunction());
    }
    if (e.hasLoadedLength()) {
        into.writeAttr(SUMO_ATTR_LENGTH, e.getLoadedLength());
    }
    if (!e.hasDefaultGeometry()) {
        into.writeAttr(SUMO_ATTR_SHAPE, e.getGeometry());
    }
    // write the lanes
    const std::vector<NBEdge::Lane>& lanes = e.getLanes();
    SUMOReal length = e.getLoadedLength();
    if (length <= 0) {
        length = (SUMOReal) .1;
    }
    for (unsigned int i = 0; i < (unsigned int) lanes.size(); i++) {
        writeLane(into, e.getID(), e.getLaneID(i), lanes[i], length, i, origNames);
    }
    // close the edge
    into.closeTag();
}
コード例 #10
0
void
NIXMLConnectionsHandler::addCrossing(const SUMOSAXAttributes& attrs) {
    bool ok = true;
    NBNode* node = 0;
    EdgeVector edges;
    const std::string nodeID = attrs.get<std::string>(SUMO_ATTR_NODE, 0, ok);
    const double width = attrs.getOpt<double>(SUMO_ATTR_WIDTH, nodeID.c_str(), ok, NBEdge::UNSPECIFIED_WIDTH, true);
    const bool discard = attrs.getOpt<bool>(SUMO_ATTR_DISCARD, nodeID.c_str(), ok, false, true);
    int tlIndex = attrs.getOpt<int>(SUMO_ATTR_TLLINKINDEX, 0, ok, -1);
    int tlIndex2 = attrs.getOpt<int>(SUMO_ATTR_TLLINKINDEX2, 0, ok, -1);
    std::vector<std::string> edgeIDs;
    if (!attrs.hasAttribute(SUMO_ATTR_EDGES)) {
        if (discard) {
            node = myNodeCont.retrieve(nodeID);
            if (node == 0) {
                WRITE_ERROR("Node '" + nodeID + "' in crossing is not known.");
                return;
            }
            node->discardAllCrossings(true);
            return;
        } else {
            WRITE_ERROR("No edges specified for crossing at node '" + nodeID + "'.");
            return;
        }
    }
    SUMOSAXAttributes::parseStringVector(attrs.get<std::string>(SUMO_ATTR_EDGES, 0, ok), edgeIDs);
    if (!ok) {
        return;
    }
    for (std::vector<std::string>::const_iterator it = edgeIDs.begin(); it != edgeIDs.end(); ++it) {
        NBEdge* edge = myEdgeCont.retrieve(*it);
        if (edge == 0) {
            WRITE_ERROR("Edge '" + (*it) + "' for crossing at node '" + nodeID + "' is not known.");
            return;
        }
        if (node == 0) {
            if (edge->getToNode()->getID() == nodeID) {
                node = edge->getToNode();
            } else if (edge->getFromNode()->getID() == nodeID) {
                node = edge->getFromNode();
            } else {
                WRITE_ERROR("Edge '" + (*it) + "' does not touch node '" + nodeID + "'.");
                return;
            }
        } else {
            if (edge->getToNode() != node && edge->getFromNode() != node) {
                WRITE_ERROR("Edge '" + (*it) + "' does not touch node '" + nodeID + "'.");
                return;
            }
        }
        edges.push_back(edge);
    }
    bool priority = attrs.getOpt<bool>(SUMO_ATTR_PRIORITY, nodeID.c_str(), ok, node->isTLControlled(), true);
    if (node->isTLControlled() && !priority) {
        // traffic_light nodes should always have priority crossings
        WRITE_WARNING("Crossing at controlled node '" + nodeID + "' must be prioritized");
        priority = true;
    }
    PositionVector customShape = attrs.getOpt<PositionVector>(SUMO_ATTR_SHAPE, 0, ok, PositionVector::EMPTY);
    if (!NBNetBuilder::transformCoordinates(customShape)) {
        WRITE_ERROR("Unable to project shape for crossing at node '" + node->getID() + "'.");
    }
    if (discard) {
        node->removeCrossing(edges);
    } else {
        if (node->checkCrossingDuplicated(edges)) {
            WRITE_ERROR("Crossing with edges '" + toString(edges) + "' already exists at node '" + node->getID() + "'.");
            return;
        }
        node->addCrossing(edges, width, priority, tlIndex, tlIndex2, customShape);
    }
}
コード例 #11
0
unsigned int
NBNodeCont::joinJunctions(SUMOReal maxDist, NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tlc) {
    NodeClusters cands;
    NodeClusters clusters;
    generateNodeClusters(maxDist, cands);
    for (NodeClusters::iterator i = cands.begin(); i != cands.end(); ++i) {
        std::set<NBNode*> cluster = (*i);
        // remove join exclusions
        for (std::set<NBNode*>::iterator j = cluster.begin(); j != cluster.end();) {
            std::set<NBNode*>::iterator check = j;
            ++j;
            if (myJoinExclusions.count((*check)->getID()) > 0) {
                cluster.erase(check);
            }
        }
        // iteratively remove the fringe
        bool pruneFringe = true;
        while (pruneFringe) {
            pruneFringe = false;
            for (std::set<NBNode*>::iterator j = cluster.begin(); j != cluster.end();) {
                std::set<NBNode*>::iterator check = j;
                NBNode* n = *check;
                ++j;
                // remove geometry-like nodes at fringe of the cluster
                // (they have 1 neighbor in the cluster and at most 1 neighbor outside the cluster)
                std::set<NBNode*> neighbors;
                std::set<NBNode*> clusterNeigbors;
                for (EdgeVector::const_iterator it_edge = n->getOutgoingEdges().begin(); it_edge != n->getOutgoingEdges().end(); ++it_edge) {
                    NBNode* neighbor = (*it_edge)->getToNode();
                    if (cluster.count(neighbor) == 0) {
                        neighbors.insert(neighbor);
                    } else {
                        clusterNeigbors.insert(neighbor);
                    }
                }
                for (EdgeVector::const_iterator it_edge = n->getIncomingEdges().begin(); it_edge != n->getIncomingEdges().end(); ++it_edge) {
                    NBNode* neighbor = (*it_edge)->getFromNode();
                    if (cluster.count(neighbor) == 0) {
                        neighbors.insert(neighbor);
                    } else {
                        clusterNeigbors.insert(neighbor);
                    }
                }
                if (neighbors.size() <= 1 && clusterNeigbors.size() == 1) {
                    cluster.erase(check);
                    pruneFringe = true; // other nodes could belong to the fringe now
                }
            }
        }
        // exclude the fromNode of a long edge if the toNode is in the cluster (and they were both added via an alternative path).
        std::set<NBNode*> toRemove;
        for (std::set<NBNode*>::iterator j = cluster.begin(); j != cluster.end(); ++j) {
            NBNode* n = *j;
            const EdgeVector& edges = n->getOutgoingEdges();
            for (EdgeVector::const_iterator it_edge = edges.begin(); it_edge != edges.end(); ++it_edge) {
                NBEdge* edge = *it_edge;
                if (cluster.count(edge->getToNode()) != 0 && edge->getLoadedLength() > maxDist) {
                    //std::cout << "long edge " << edge->getID() << " (" << edge->getLoadedLength() << ", max=" << maxDist << ")\n";
                    toRemove.insert(n);
                    toRemove.insert(edge->getToNode());
                }
            }
        }
        for (std::set<NBNode*>::iterator j = toRemove.begin(); j != toRemove.end(); ++j) {
            cluster.erase(*j);
        }
        if (cluster.size() > 1) {
            // check for clusters which are to complex and probably won't work very well
            // we count the incoming edges of the final junction
            std::set<NBEdge*> finalIncoming;
            std::set<NBEdge*> finalOutgoing;
            std::vector<std::string> nodeIDs;
            for (std::set<NBNode*>::const_iterator j = cluster.begin(); j != cluster.end(); ++j) {
                nodeIDs.push_back((*j)->getID());
                for (EdgeVector::const_iterator it_edge = (*j)->getIncomingEdges().begin(); it_edge != (*j)->getIncomingEdges().end(); ++it_edge) {
                    NBEdge* edge = *it_edge;
                    if (cluster.count(edge->getFromNode()) == 0) {
                        // incoming edge, does not originate in the cluster
                        finalIncoming.insert(edge);
                    }
                }
                for (EdgeVector::const_iterator it_edge = (*j)->getOutgoingEdges().begin(); it_edge != (*j)->getOutgoingEdges().end(); ++it_edge) {
                    NBEdge* edge = *it_edge;
                    if (cluster.count(edge->getToNode()) == 0) {
                        // outgoing edge, does not end in the cluster
                        finalOutgoing.insert(edge);
                    }
                }

            }
            if (finalIncoming.size() > 4) {
                std::sort(nodeIDs.begin(), nodeIDs.end());
                WRITE_WARNING("Not joining junctions " + joinToStringSorting(nodeIDs, ',') + " because the cluster is too complex (" + toString(finalIncoming.size()) + " incoming edges)");
            } else {
                // check for incoming parallel edges
                const SUMOReal PARALLEL_INCOMING_THRESHOLD = 10.0;
                bool foundParallel = false;
                for (std::set<NBEdge*>::const_iterator j = finalIncoming.begin(); j != finalIncoming.end() && !foundParallel; ++j) {
                    for (std::set<NBEdge*>::const_iterator k = finalIncoming.begin(); k != finalIncoming.end() && !foundParallel; ++k) {
                        if ((*j) != (*k) && fabs((*j)->getAngleAtNode((*j)->getToNode()) - (*k)->getAngleAtNode((*k)->getToNode())) < PARALLEL_INCOMING_THRESHOLD) {
                            std::vector<std::string> parallelEdgeIDs;
                            parallelEdgeIDs.push_back((*j)->getID());
                            parallelEdgeIDs.push_back((*k)->getID());
                            std::sort(parallelEdgeIDs.begin(), parallelEdgeIDs.end());
                            WRITE_WARNING("Not joining junctions " + joinToStringSorting(nodeIDs, ',') + " because the cluster is too complex (parallel incoming "
                                          + joinToString(parallelEdgeIDs, ',') + ")");
                            foundParallel = true;
                        }
                    }
                }
                // check for outgoing parallel edges
                for (std::set<NBEdge*>::const_iterator j = finalOutgoing.begin(); j != finalOutgoing.end() && !foundParallel; ++j) {
                    for (std::set<NBEdge*>::const_iterator k = finalOutgoing.begin(); k != finalOutgoing.end() && !foundParallel; ++k) {
                        if ((*j) != (*k) && fabs((*j)->getAngleAtNode((*j)->getFromNode()) - (*k)->getAngleAtNode((*k)->getFromNode())) < PARALLEL_INCOMING_THRESHOLD) {
                            std::vector<std::string> parallelEdgeIDs;
                            parallelEdgeIDs.push_back((*j)->getID());
                            parallelEdgeIDs.push_back((*k)->getID());
                            std::sort(parallelEdgeIDs.begin(), parallelEdgeIDs.end());
                            WRITE_WARNING("Not joining junctions " + joinToStringSorting(nodeIDs, ',') + " because the cluster is too complex (parallel outgoing "
                                          + joinToStringSorting(parallelEdgeIDs, ',') + ")");
                            foundParallel = true;
                        }
                    }
                }
                if (!foundParallel && cluster.size() > 1) {
                    // compute all connected components of this cluster
                    // (may be more than 1 if intermediate nodes were removed)
                    NodeClusters components;
                    for (std::set<NBNode*>::iterator j = cluster.begin(); j != cluster.end(); ++j) {
                        // merge all connected components into newComp
                        std::set<NBNode*> newComp;
                        NBNode* current = *j;
                        //std::cout << "checking connectivity for " << current->getID() << "\n";
                        newComp.insert(current);
                        for (NodeClusters::iterator it_comp = components.begin(); it_comp != components.end();) {
                            NodeClusters::iterator check = it_comp;
                            //std::cout << "   connected with " << toString(*check) << "?\n";
                            bool connected = false;
                            for (std::set<NBNode*>::iterator k = (*check).begin(); k != (*check).end(); ++k) {
                                if (current->getConnectionTo(*k) != 0 || (*k)->getConnectionTo(current) != 0) {
                                    //std::cout << "joining with connected component " << toString(*check) << "\n";
                                    newComp.insert((*check).begin(), (*check).end());
                                    it_comp = components.erase(check);
                                    connected = true;
                                    break;
                                }
                            }
                            if (!connected) {
                                it_comp++;
                            }
                        }
                        //std::cout << "adding new component " << toString(newComp) << "\n";
                        components.push_back(newComp);
                    }
                    for (NodeClusters::iterator it_comp = components.begin(); it_comp != components.end(); ++it_comp) {
                        if ((*it_comp).size() > 1) {
                            //std::cout << "adding cluster " << toString(*it_comp) << "\n";
                            clusters.push_back(*it_comp);
                        }
                    }
                }
            }
        }
    }
    joinNodeClusters(clusters, dc, ec, tlc);
    return (int)clusters.size();
}
コード例 #12
0
void
NBRampsComputer::buildOffRamp(NBNode* cur, NBNodeCont& nc, NBEdgeCont& ec, NBDistrictCont& dc, SUMOReal rampLength, bool dontSplit, std::set<NBEdge*>& incremented) {
    NBEdge* potHighway, *potRamp, *prev;
    getOffRampEdges(cur, &potHighway, &potRamp, &prev);
    // compute the number of lanes to append
    const unsigned int firstLaneNumber = prev->getNumLanes();
    int toAdd = (potRamp->getNumLanes() + potHighway->getNumLanes()) - firstLaneNumber;
    NBEdge* first = prev;
    NBEdge* last = prev;
    NBEdge* curr = prev;
    if (toAdd > 0 && find(incremented.begin(), incremented.end(), prev) == incremented.end()) {
        SUMOReal currLength = 0;
        while (curr != 0 && currLength + curr->getGeometry().length() - POSITION_EPS < rampLength) {
            if (find(incremented.begin(), incremented.end(), curr) == incremented.end()) {
                curr->incLaneNo(toAdd);
                curr->invalidateConnections(true);
                incremented.insert(curr);
                moveRampRight(curr, toAdd);
                currLength += curr->getLength(); // !!! loaded length?
                last = curr;
            }
            NBNode* prevN = curr->getFromNode();
            if (prevN->getIncomingEdges().size() == 1) {
                curr = prevN->getIncomingEdges()[0];
                if (curr->getNumLanes() != firstLaneNumber) {
                    // the number of lanes changes along the computation; we'll stop...
                    curr = 0;
                } else if (last->isTurningDirectionAt(curr)) {
                    // turnarounds certainly should not be included in a ramp
                    curr = 0;
                } else if (curr == potHighway || curr == potRamp) {
                    // circular connectivity. do not split!
                    curr = 0;
                }
            } else {
                // ambigous; and, in fact, what should it be? ...stop
                curr = 0;
            }
        }
        // check whether a further split is necessary
        if (curr != 0 && !dontSplit && currLength - POSITION_EPS < rampLength && curr->getNumLanes() == firstLaneNumber && find(incremented.begin(), incremented.end(), curr) == incremented.end()) {
            // there is enough place to build a ramp; do it
            bool wasFirst = first == curr;
            Position pos = curr->getGeometry().positionAtOffset(curr->getGeometry().length() - (rampLength  - currLength));
            NBNode* rn = new NBNode(curr->getID() + "-AddedOffRampNode", pos);
            if (!nc.insert(rn)) {
                throw ProcessError("Ups - could not build on-ramp for edge '" + curr->getID() + "' (node could not be build)!");
            }
            std::string name = curr->getID();
            bool ok = ec.splitAt(dc, curr, rn, curr->getID(), curr->getID() + "-AddedOffRampEdge", curr->getNumLanes(), curr->getNumLanes() + toAdd);
            if (!ok) {
                WRITE_ERROR("Ups - could not build on-ramp for edge '" + curr->getID() + "'!");
                return;
            }
            curr = ec.retrieve(name + "-AddedOffRampEdge");
            incremented.insert(curr);
            last = curr;
            moveRampRight(curr, toAdd);
            if (wasFirst) {
                first = curr;
            }
        }
        if (curr == prev && dontSplit) {
            WRITE_WARNING("Could not build off-ramp for edge '"  + curr->getID() + "' due to option '--ramps.no-split'");
            return;
        }
    }
    // set connections from added ramp to ramp/highway
    if (!first->addLane2LaneConnections(potRamp->getNumLanes(), potHighway, 0, MIN2(first->getNumLanes() - 1, potHighway->getNumLanes()), NBEdge::L2L_VALIDATED, true)) {
        throw ProcessError("Could not set connection!");
    }
    if (!first->addLane2LaneConnections(0, potRamp, 0, potRamp->getNumLanes(), NBEdge::L2L_VALIDATED, false)) {
        throw ProcessError("Could not set connection!");
    }
    // patch ramp geometry
    PositionVector p = potRamp->getGeometry();
    p.pop_front();
    p.push_front(first->getLaneShape(0)[-1]);
    potRamp->setGeometry(p);
}
コード例 #13
0
ファイル: NIXMLEdgesHandler.cpp プロジェクト: planetsumo/sumo
void
NIXMLEdgesHandler::myEndElement(int element) {
    if (element == SUMO_TAG_EDGE && myCurrentEdge != 0) {
        // add bike lane, wait until lanes are loaded to avoid building if it already exists
        if (myBikeLaneWidth != NBEdge::UNSPECIFIED_WIDTH) {
            myCurrentEdge->addBikeLane(myBikeLaneWidth);
        }
        // add sidewalk, wait until lanes are loaded to avoid building if it already exists
        if (mySidewalkWidth != NBEdge::UNSPECIFIED_WIDTH) {
            myCurrentEdge->addSidewalk(mySidewalkWidth);
        }
        if (!myIsUpdate) {
            try {
                if (!myEdgeCont.insert(myCurrentEdge)) {
                    WRITE_ERROR("Duplicate edge occured. ID='" + myCurrentID + "'");
                    delete myCurrentEdge;
                }
            } catch (InvalidArgument& e) {
                WRITE_ERROR(e.what());
                throw;
            } catch (...) {
                WRITE_ERROR("An important information is missing in edge '" + myCurrentID + "'.");
            }
        }
        if (mySplits.size() != 0) {
            std::vector<Split>::iterator i;
            NBEdge* e = myCurrentEdge;
            sort(mySplits.begin(), mySplits.end(), split_sorter());
            int noLanesMax = e->getNumLanes();
            // compute the node positions and sort the lanes
            for (i = mySplits.begin(); i != mySplits.end(); ++i) {
                sort((*i).lanes.begin(), (*i).lanes.end());
                noLanesMax = MAX2(noLanesMax, (int)(*i).lanes.size());
            }
            // split the edge
            std::vector<int> currLanes;
            for (int l = 0; l < e->getNumLanes(); ++l) {
                currLanes.push_back(l);
            }
            if (e->getNumLanes() != (int)mySplits.back().lanes.size()) {
                // invalidate traffic light definitions loaded from a SUMO network
                // XXX it would be preferable to reconstruct the phase definitions heuristically
                e->getToNode()->invalidateTLS(myTLLogicCont);
                // if the number of lanes changes the connections should be
                // recomputed
                e->invalidateConnections(true);
            }

            std::string firstID = "";
            SUMOReal seen = 0;
            for (i = mySplits.begin(); i != mySplits.end(); ++i) {
                const Split& exp = *i;
                assert(exp.lanes.size() != 0);
                if (exp.pos > 0 && e->getGeometry().length() + seen > exp.pos && exp.pos > seen) {
                    if (myNodeCont.insert(exp.node)) {
                        myNodeCont.markAsSplit(exp.node);
                        //  split the edge
                        std::string idBefore = exp.idBefore == "" ? e->getID() : exp.idBefore;
                        std::string idAfter = exp.idAfter == "" ? exp.node->getID() : exp.idAfter;
                        if (firstID == "") {
                            firstID = idBefore;
                        }
                        myEdgeCont.splitAt(myDistrictCont, e, exp.pos - seen, exp.node,
                                           idBefore, idAfter, e->getNumLanes(), (int) exp.lanes.size(), exp.speed);
                        seen = exp.pos;
                        std::vector<int> newLanes = exp.lanes;
                        NBEdge* pe = myEdgeCont.retrieve(idBefore);
                        NBEdge* ne = myEdgeCont.retrieve(idAfter);
                        // reconnect lanes
                        pe->invalidateConnections(true);
                        //  new on right
                        int rightMostP = currLanes[0];
                        int rightMostN = newLanes[0];
                        for (int l = 0; l < (int) rightMostP - (int) rightMostN; ++l) {
                            pe->addLane2LaneConnection(0, ne, l, NBEdge::L2L_VALIDATED, true);
                        }
                        //  new on left
                        int leftMostP = currLanes.back();
                        int leftMostN = newLanes.back();
                        for (int l = 0; l < (int) leftMostN - (int) leftMostP; ++l) {
                            pe->addLane2LaneConnection(pe->getNumLanes() - 1, ne, leftMostN - l - rightMostN, NBEdge::L2L_VALIDATED, true);
                        }
                        //  all other connected
                        for (int l = 0; l < noLanesMax; ++l) {
                            if (find(currLanes.begin(), currLanes.end(), l) == currLanes.end()) {
                                continue;
                            }
                            if (find(newLanes.begin(), newLanes.end(), l) == newLanes.end()) {
                                continue;
                            }
                            pe->addLane2LaneConnection(l - rightMostP, ne, l - rightMostN, NBEdge::L2L_VALIDATED, true);
                        }
                        // move to next
                        e = ne;
                        currLanes = newLanes;
                    } else {
                        WRITE_WARNING("Error on parsing a split (edge '" + myCurrentID + "').");
                    }
                }  else if (exp.pos == 0) {
                    const int laneCountDiff = e->getNumLanes() - (int)exp.lanes.size();
                    if (laneCountDiff < 0) {
                        e->incLaneNo(-laneCountDiff);
                    } else {
                        e->decLaneNo(laneCountDiff);
                    }
                    currLanes = exp.lanes;
                    // invalidate traffic light definition loaded from a SUMO network
                    // XXX it would be preferable to reconstruct the phase definitions heuristically
                    e->getFromNode()->invalidateTLS(myTLLogicCont);
                } else {
                    WRITE_WARNING("Split at '" + toString(exp.pos) + "' lies beyond the edge's length (edge '" + myCurrentID + "').");
                }
            }
            // patch lane offsets
            e = myEdgeCont.retrieve(firstID);
            if (mySplits.front().pos != 0) {
                // add a dummy split at the beginning to ensure correct offset
                Split start;
                start.pos = 0;
                for (int lane = 0; lane < (int)e->getNumLanes(); ++lane) {
                    start.lanes.push_back(lane);
                }
                mySplits.insert(mySplits.begin(), start);
            }
            i = mySplits.begin();
            for (; i != mySplits.end(); ++i) {
                int maxLeft = (*i).lanes.back();
                SUMOReal offset = 0;
                if (maxLeft < noLanesMax) {
                    if (e->getLaneSpreadFunction() == LANESPREAD_RIGHT) {
                        offset = SUMO_const_laneWidthAndOffset * (noLanesMax - 1 - maxLeft);
                    } else {
                        offset = SUMO_const_halfLaneAndOffset * (noLanesMax - 1 - maxLeft);
                    }
                }
                int maxRight = (*i).lanes.front();
                if (maxRight > 0 && e->getLaneSpreadFunction() == LANESPREAD_CENTER) {
                    offset -= SUMO_const_halfLaneAndOffset * maxRight;
                }
                if (offset != 0) {
                    PositionVector g = e->getGeometry();
                    g.move2side(offset);
                    e->setGeometry(g);
                }
                if (e->getToNode()->getOutgoingEdges().size() != 0) {
                    e = e->getToNode()->getOutgoingEdges()[0];
                }
            }
        }
    }
}
コード例 #14
0
void
NIVissimDistrictConnection::dict_BuildDistricts(NBDistrictCont& dc,
        NBEdgeCont& ec,
        NBNodeCont& nc/*,
                                                                                NBDistribution &distc*/) {
    // add the sources and sinks
    //  their normalised probability is computed within NBDistrict
    //   to avoid SUMOReal code writing and more securty within the converter
    //  go through the district table
    for (std::map<int, std::vector<int> >::iterator k = myDistrictsConnections.begin(); k != myDistrictsConnections.end(); k++) {
        // get the connections
        const std::vector<int>& connections = (*k).second;
        // retrieve the current district
        NBDistrict* district =
            dc.retrieve(toString<int>((*k).first));
        NBNode* districtNode = nc.retrieve("District" + district->getID());
        assert(district != 0 && districtNode != 0);

        for (std::vector<int>::const_iterator l = connections.begin(); l != connections.end(); l++) {
            NIVissimDistrictConnection* c = dictionary(*l);
            // get the edge to connect the parking place to
            NBEdge* e = ec.retrieve(toString<int>(c->myEdgeID));
            if (e == 0) {
                e = ec.retrievePossiblySplit(toString<int>(c->myEdgeID), c->myPosition);
            }
            if (e == 0) {
                WRITE_WARNING("Could not build district '" + toString<int>((*k).first) + "' - edge '" + toString<int>(c->myEdgeID) + "' is missing.");
                continue;
            }
            std::string id = "ParkingPlace" + toString<int>(*l);
            NBNode* parkingPlace = nc.retrieve(id);
            if (parkingPlace == 0) {
                SUMOReal pos = c->getPosition();
                if (pos < e->getLength() - pos) {
                    parkingPlace = e->getFromNode();
                    parkingPlace->invalidateIncomingConnections();
                } else {
                    parkingPlace = e->getToNode();
                    parkingPlace->invalidateOutgoingConnections();
                }
            }
            assert(
                e->getToNode() == parkingPlace
                ||
                e->getFromNode() == parkingPlace);

            // build the connection to the source
            if (e->getFromNode() == parkingPlace) {
                id = "VissimFromParkingplace" + toString<int>((*k).first) + "-" + toString<int>(c->myID);
                NBEdge* source =
                    new NBEdge(id, districtNode, parkingPlace,
                               "Connection", c->getMeanSpeed(/*distc*/) / (SUMOReal) 3.6, 3, -1,
                               NBEdge::UNSPECIFIED_WIDTH, NBEdge::UNSPECIFIED_OFFSET);
                if (!ec.insert(source)) { // !!! in den Konstruktor
                    throw 1; // !!!
                }
                SUMOReal percNormed =
                    c->myPercentages[(*k).first];
                if (!district->addSource(source, percNormed)) {
                    throw 1;
                }
            }

            // build the connection to the destination
            if (e->getToNode() == parkingPlace) {
                id = "VissimToParkingplace"  + toString<int>((*k).first) + "-" + toString<int>(c->myID);
                NBEdge* destination =
                    new NBEdge(id, parkingPlace, districtNode,
                               "Connection", (SUMOReal) 100 / (SUMOReal) 3.6, 2, -1,
                               NBEdge::UNSPECIFIED_WIDTH, NBEdge::UNSPECIFIED_OFFSET);
                if (!ec.insert(destination)) { // !!! (in den Konstruktor)
                    throw 1; // !!!
                }
                SUMOReal percNormed2 =
                    c->myPercentages[(*k).first];
                if (!district->addSink(destination, percNormed2)) {
                    throw 1; // !!!
                }
            }

            /*
            if(e->getToNode()==districtNode) {
            SUMOReal percNormed =
                c->myPercentages[(*k).first];
            district->addSink(e, percNormed);
            }
            if(e->getFromNode()==districtNode) {
            SUMOReal percNormed =
                c->myPercentages[(*k).first];
            district->addSource(e, percNormed);
            }
            */
        }

        /*
        // add them as sources and sinks to the current district
        for(std::vector<int>::const_iterator l=connections.begin(); l!=connections.end(); l++) {
            // get the current connections
            NIVissimDistrictConnection *c = dictionary(*l);
            // get the edge to connect the parking place to
            NBEdge *e = NBEdgeCont::retrieve(toString<int>(c->myEdgeID));
            Position edgepos = c->geomPosition();
            NBNode *edgeend = e->tryGetNodeAtPosition(c->myPosition,
                e->getLength()/4.0);
            if(edgeend==0) {
                // Edge splitting omitted on build district connections by now
                assert(false);
            }

            // build the district-node if not yet existing
            std::string id = "VissimParkingplace" + district->getID();
            NBNode *districtNode = nc.retrieve(id);
            assert(districtNode!=0);

            if(e->getToNode()==edgeend) {
                // build the connection to the source
                id = std::string("VissimFromParkingplace")
                    + toString<int>((*k).first) + "-"
                    + toString<int>(c->myID);
                NBEdge *source =
                    new NBEdge(id, id, districtNode, edgeend,
                    "Connection", 100/3.6, 2, 100, 0,
                    NBEdge::EDGEFUNCTION_SOURCE);
                NBEdgeCont::insert(source); // !!! (in den Konstruktor)
                SUMOReal percNormed =
                    c->myPercentages[(*k).first];
                district->addSource(source, percNormed);
            } else {
                // build the connection to the destination
                id = std::string("VissimToParkingplace")
                    + toString<int>((*k).first) + "-"
                    + toString<int>(c->myID);
                NBEdge *destination =
                    new NBEdge(id, id, edgeend, districtNode,
                    "Connection", 100/3.6, 2, 100, 0,
                    NBEdge::EDGEFUNCTION_SINK);
                NBEdgeCont::insert(destination); // !!! (in den Konstruktor)

                // add both the source and the sink to the district
                SUMOReal percNormed =
                    c->myPercentages[(*k).first];
                district->addSink(destination, percNormed);
            }
        }
        */
    }
}
コード例 #15
0
void
NIImporter_VISUM::parse_Lanes() {
    // get the node
    NBNode* node = getNamedNode("KNOTNR");
    // get the edge
    NBEdge* baseEdge = getNamedEdge("STRNR");
    NBEdge* edge = getNamedEdgeContinuating("STRNR", node);
    // check
    if (node == 0 || edge == 0) {
        return;
    }
    // get the lane
    std::string laneS = myLineParser.know("FSNR")
                        ? NBHelpers::normalIDRepresentation(myLineParser.get("FSNR"))
                        : NBHelpers::normalIDRepresentation(myLineParser.get("NR"));
    int lane = -1;
    try {
        lane = TplConvert::_2int(laneS.c_str());
    } catch (NumberFormatException&) {
        WRITE_ERROR("A lane number for edge '" + edge->getID() + "' is not numeric (" + laneS + ").");
        return;
    }
    lane -= 1;
    if (lane < 0) {
        WRITE_ERROR("A lane number for edge '" + edge->getID() + "' is not positive (" + laneS + ").");
        return;
    }
    // get the direction
    std::string dirS = NBHelpers::normalIDRepresentation(myLineParser.get("RICHTTYP"));
    int prevLaneNo = baseEdge->getNumLanes();
    if ((dirS == "1" && !(node->hasIncoming(edge))) || (dirS == "0" && !(node->hasOutgoing(edge)))) {
        // get the last part of the turnaround direction
        edge = getReversedContinuating(edge, node);
    }
    // get the length
    std::string lengthS = NBHelpers::normalIDRepresentation(myLineParser.get("LAENGE"));
    SUMOReal length = -1;
    try {
        length = TplConvert::_2SUMOReal(lengthS.c_str());
    } catch (NumberFormatException&) {
        WRITE_ERROR("A lane length for edge '" + edge->getID() + "' is not numeric (" + lengthS + ").");
        return;
    }
    if (length < 0) {
        WRITE_ERROR("A lane length for edge '" + edge->getID() + "' is not positive (" + lengthS + ").");
        return;
    }
    //
    if (dirS == "1") {
        lane -= prevLaneNo;
    }
    //
    if (length == 0) {
        if ((int) edge->getNumLanes() > lane) {
            // ok, we know this already...
            return;
        }
        // increment by one
        edge->incLaneNo(1);
    } else {
        // check whether this edge already has been created
        if (edge->getID().substr(edge->getID().length() - node->getID().length() - 1) == "_" + node->getID()) {
            if (edge->getID().substr(edge->getID().find('_')) == "_" + toString(length) + "_" + node->getID()) {
                if ((int) edge->getNumLanes() > lane) {
                    // ok, we know this already...
                    return;
                }
                // increment by one
                edge->incLaneNo(1);
                return;
            }
        }
        // nope, we have to split the edge...
        //  maybe it is not the proper edge to split - VISUM seems not to sort the splits...
        bool mustRecheck = true;
        SUMOReal seenLength = 0;
        while (mustRecheck) {
            if (edge->getID().substr(edge->getID().length() - node->getID().length() - 1) == "_" + node->getID()) {
                // ok, we have a previously created edge here
                std::string sub = edge->getID();
                sub = sub.substr(sub.rfind('_', sub.rfind('_') - 1));
                sub = sub.substr(1, sub.find('_', 1) - 1);
                SUMOReal dist = TplConvert::_2SUMOReal(sub.c_str());
                if (dist < length) {
                    seenLength += edge->getLength();
                    if (dirS == "1") {
                        // incoming -> move back
                        edge = edge->getFromNode()->getIncomingEdges()[0];
                    } else {
                        // outgoing -> move forward
                        edge = edge->getToNode()->getOutgoingEdges()[0];
                    }
                } else {
                    mustRecheck = false;
                }
            } else {
                // we have the center edge - do not continue...
                mustRecheck = false;
            }
        }
        // compute position
        Position p;
        SUMOReal useLength = length - seenLength;
        useLength = edge->getLength() - useLength;
        std::string edgeID = edge->getID();
        p = edge->getGeometry().positionAtLengthPosition(useLength);
        if (edgeID.substr(edgeID.length() - node->getID().length() - 1) == "_" + node->getID()) {
            edgeID = edgeID.substr(0, edgeID.find('_'));
        }
        NBNode* rn = new NBNode(edgeID + "_" +  toString((size_t) length) + "_" + node->getID(), p);
        if (!myNetBuilder.getNodeCont().insert(rn)) {
            throw ProcessError("Ups - could not insert node!");
        }
        std::string nid = edgeID + "_" +  toString((size_t) length) + "_" + node->getID();
        myNetBuilder.getEdgeCont().splitAt(myNetBuilder.getDistrictCont(), edge, useLength, rn,
                                           edge->getID(), nid, edge->getNumLanes() + 0, edge->getNumLanes() + 1);
        NBEdge* nedge = myNetBuilder.getEdgeCont().retrieve(nid);
        nedge = nedge->getToNode()->getOutgoingEdges()[0];
        while (nedge->getID().substr(nedge->getID().length() - node->getID().length() - 1) == "_" + node->getID()) {
            assert(nedge->getToNode()->getOutgoingEdges().size() > 0);
            nedge->incLaneNo(1);
            nedge = nedge->getToNode()->getOutgoingEdges()[0];
        }
    }
}
コード例 #16
0
void
NBNodeCont::removeIsolatedRoads(NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tc) {
    UNUSED_PARAMETER(tc);
    // Warn of isolated edges, i.e. a single edge with no connection to another edge
    int edgeCounter = 0;
    const std::vector<std::string>& edgeNames = ec.getAllNames();
    for (std::vector<std::string>::const_iterator it = edgeNames.begin(); it != edgeNames.end(); ++it) {
        // Test whether this node starts at a dead end, i.e. it has only one adjacent node
        // to which an edge exists and from which an edge may come.
        NBEdge* e = ec.retrieve(*it);
        if (e == 0) {
            continue;
        }
        NBNode* from = e->getFromNode();
        const EdgeVector& outgoingEdges = from->getOutgoingEdges();
        if (outgoingEdges.size() != 1) {
            // At this node, several edges or no edge start; so, this node is no dead end.
            continue;
        }
        const EdgeVector& incomingEdges = from->getIncomingEdges();
        if (incomingEdges.size() > 1) {
            // At this node, several edges end; so, this node is no dead end.
            continue;
        } else if (incomingEdges.size() == 1) {
            NBNode* fromNodeOfIncomingEdge = incomingEdges[0]->getFromNode();
            NBNode* toNodeOfOutgoingEdge = outgoingEdges[0]->getToNode();
            if (fromNodeOfIncomingEdge != toNodeOfOutgoingEdge) {
                // At this node, an edge ends which is not the inverse direction of
                // the starting node.
                continue;
            }
        }
        // Now we know that the edge e starts a dead end.
        // Next we test if the dead end is isolated, i.e. does not lead to a junction
        bool hasJunction = false;
        EdgeVector road;
        NBEdge* eOld = 0;
        NBNode* to;
        std::set<NBNode*> adjacentNodes;
        do {
            road.push_back(e);
            eOld = e;
            from = e->getFromNode();
            to = e->getToNode();
            const EdgeVector& outgoingEdgesOfToNode = to->getOutgoingEdges();
            const EdgeVector& incomingEdgesOfToNode = to->getIncomingEdges();
            adjacentNodes.clear();
            for (EdgeVector::const_iterator itOfOutgoings = outgoingEdgesOfToNode.begin(); itOfOutgoings != outgoingEdgesOfToNode.end(); ++itOfOutgoings) {
                if ((*itOfOutgoings)->getToNode() != from        // The back path
                        && (*itOfOutgoings)->getToNode() != to   // A loop / dummy edge
                   ) {
                    e = *itOfOutgoings; // Probably the next edge
                }
                adjacentNodes.insert((*itOfOutgoings)->getToNode());
            }
            for (EdgeVector::const_iterator itOfIncomings = incomingEdgesOfToNode.begin(); itOfIncomings != incomingEdgesOfToNode.end(); ++itOfIncomings) {
                adjacentNodes.insert((*itOfIncomings)->getFromNode());
            }
            adjacentNodes.erase(to);  // Omit loops
            if (adjacentNodes.size() > 2) {
                hasJunction = true;
            }
        } while (!hasJunction && eOld != e);
        if (!hasJunction) {
            edgeCounter +=  int(road.size());
            std::string warningString = "Removed a road without junctions: ";
            for (EdgeVector::iterator roadIt = road.begin(); roadIt != road.end(); ++roadIt) {
                if (roadIt == road.begin()) {
                    warningString += (*roadIt)->getID();
                } else {
                    warningString += ", " + (*roadIt)->getID();
                }

                NBNode* fromNode = (*roadIt)->getFromNode();
                NBNode* toNode = (*roadIt)->getToNode();
                ec.erase(dc, *roadIt);
                if (fromNode->getIncomingEdges().size() == 0 && fromNode->getOutgoingEdges().size() == 0) {
                    // Node is empty; can be removed
                    erase(fromNode);
                }
                if (toNode->getIncomingEdges().size() == 0 && toNode->getOutgoingEdges().size() == 0) {
                    // Node is empty; can be removed
                    erase(toNode);
                }
            }
            WRITE_WARNING(warningString);
        }
    }
    if (edgeCounter > 0 && !OptionsCont::getOptions().getBool("remove-edges.isolated")) {
        WRITE_WARNING("Detected isolated roads. Use the option --remove-edges.isolated to get a list of all affected edges.");
    }
}
コード例 #17
0
void
NIXMLEdgesHandler::myEndElement(int element) {
    if (element == SUMO_TAG_EDGE && myCurrentEdge != 0) {
        if (!myIsUpdate) {
            try {
                if (!myEdgeCont.insert(myCurrentEdge)) {
                    WRITE_ERROR("Duplicate edge occured. ID='" + myCurrentID + "'");
                    delete myCurrentEdge;
                }
            } catch (InvalidArgument& e) {
                WRITE_ERROR(e.what());
                throw;
            } catch (...) {
                WRITE_ERROR("An important information is missing in edge '" + myCurrentID + "'.");
            }
        }
        if (mySplits.size() != 0) {
            std::vector<Split>::iterator i;
            NBEdge* e = myCurrentEdge;
            sort(mySplits.begin(), mySplits.end(), split_sorter());
            unsigned int noLanesMax = e->getNumLanes();
            // compute the node positions and sort the lanes
            for (i = mySplits.begin(); i != mySplits.end(); ++i) {
                (*i).gpos = e->getGeometry().positionAtOffset((*i).pos);
                sort((*i).lanes.begin(), (*i).lanes.end());
                noLanesMax = MAX2(noLanesMax, (unsigned int)(*i).lanes.size());
            }
            // invalidate traffic light definitions loaded from a SUMO network
            // XXX it would be preferable to reconstruct the phase definitions heuristically
            e->getToNode()->invalidateTLS(myTLLogicCont);
            e->invalidateConnections(true);

            // split the edge
            std::vector<int> currLanes;
            for (unsigned int l = 0; l < e->getNumLanes(); ++l) {
                currLanes.push_back(l);
            }
            std::string edgeid = e->getID();
            SUMOReal seen = 0;
            for (i = mySplits.begin(); i != mySplits.end(); ++i) {
                const Split& exp = *i;
                assert(exp.lanes.size() != 0);
                if (exp.pos > 0 && e->getGeometry().length() + seen > exp.pos && exp.pos > seen) {
                    std::string nid = edgeid + "." +  toString(exp.nameid);
                    NBNode* rn = new NBNode(nid, exp.gpos);
                    if (myNodeCont.insert(rn)) {
                        //  split the edge
                        std::string nid = myCurrentID + "." +  toString(exp.nameid);
                        std::string pid = e->getID();
                        myEdgeCont.splitAt(myDistrictCont, e, exp.pos - seen, rn,
                                           pid, nid, e->getNumLanes(), (unsigned int) exp.lanes.size());
                        seen = exp.pos;
                        std::vector<int> newLanes = exp.lanes;
                        NBEdge* pe = myEdgeCont.retrieve(pid);
                        NBEdge* ne = myEdgeCont.retrieve(nid);
                        // reconnect lanes
                        pe->invalidateConnections(true);
                        //  new on right
                        unsigned int rightMostP = currLanes[0];
                        unsigned int rightMostN = newLanes[0];
                        for (int l = 0; l < (int) rightMostP - (int) rightMostN; ++l) {
                            pe->addLane2LaneConnection(0, ne, l, NBEdge::L2L_VALIDATED, true);
                        }
                        //  new on left
                        unsigned int leftMostP = currLanes.back();
                        unsigned int leftMostN = newLanes.back();
                        for (int l = 0; l < (int) leftMostN - (int) leftMostP; ++l) {
                            pe->addLane2LaneConnection(pe->getNumLanes() - 1, ne, leftMostN - l - rightMostN, NBEdge::L2L_VALIDATED, true);
                        }
                        //  all other connected
                        for (unsigned int l = 0; l < noLanesMax; ++l) {
                            if (find(currLanes.begin(), currLanes.end(), l) == currLanes.end()) {
                                continue;
                            }
                            if (find(newLanes.begin(), newLanes.end(), l) == newLanes.end()) {
                                continue;
                            }
                            pe->addLane2LaneConnection(l - rightMostP, ne, l - rightMostN, NBEdge::L2L_VALIDATED, true);
                        }
                        // move to next
                        e = ne;
                        currLanes = newLanes;
                    } else {
                        WRITE_WARNING("Error on parsing a split (edge '" + myCurrentID + "').");
                    }
                }  else if (exp.pos == 0) {
                    if (e->getNumLanes() < exp.lanes.size()) {
                        e->incLaneNo((int) exp.lanes.size() - e->getNumLanes());
                    } else {
                        e->decLaneNo(e->getNumLanes() - (int) exp.lanes.size());
                    }
                    currLanes = exp.lanes;
                    // invalidate traffic light definition loaded from a SUMO network
                    // XXX it would be preferable to reconstruct the phase definitions heuristically
                    e->getFromNode()->invalidateTLS(myTLLogicCont);
                } else {
                    WRITE_WARNING("Split at '" + toString(exp.pos) + "' lies beyond the edge's length (edge '" + myCurrentID + "').");
                }
            }
            // patch lane offsets
            e = myEdgeCont.retrieve(edgeid);
            i = mySplits.begin();
            if ((*i).pos != 0) {
                e = e->getToNode()->getOutgoingEdges()[0];
            }
            for (; i != mySplits.end(); ++i) {
                unsigned int maxLeft = (*i).lanes.back();
                SUMOReal offset = 0;
                if (maxLeft < noLanesMax) {
                    if (e->getLaneSpreadFunction() == LANESPREAD_RIGHT) {
                        offset = SUMO_const_laneWidthAndOffset * (noLanesMax - 1 - maxLeft);
                    } else {
                        offset = SUMO_const_halfLaneAndOffset * (noLanesMax - 1 - maxLeft);
                    }
                }
                unsigned int maxRight = (*i).lanes.front();
                if (maxRight > 0 && e->getLaneSpreadFunction() == LANESPREAD_CENTER) {
                    offset -= SUMO_const_halfLaneAndOffset * maxRight;
                }
                if (offset != 0) {
                    PositionVector g = e->getGeometry();
                    g.move2side(offset);
                    e->setGeometry(g);
                }
                if (e->getToNode()->getOutgoingEdges().size() != 0) {
                    e = e->getToNode()->getOutgoingEdges()[0];
                }
            }
        }
    }
}
コード例 #18
0
ファイル: NBEdgeCont.cpp プロジェクト: cathyyul/sumo-0.18
void
NBEdgeCont::joinSameNodeConnectingEdges(NBDistrictCont& dc,
                                        NBTrafficLightLogicCont& tlc,
                                        EdgeVector edges) {
    // !!! Attention!
    //  No merging of the geometry to come is being done
    //  The connections are moved from one edge to another within
    //   the replacement where the edge is a node's incoming edge.

    // count the number of lanes, the speed and the id
    unsigned int nolanes = 0;
    SUMOReal speed = 0;
    int priority = 0;
    std::string id;
    sort(edges.begin(), edges.end(), NBContHelper::same_connection_edge_sorter());
    // retrieve the connected nodes
    NBEdge* tpledge = *(edges.begin());
    NBNode* from = tpledge->getFromNode();
    NBNode* to = tpledge->getToNode();
    EdgeVector::const_iterator i;
    for (i = edges.begin(); i != edges.end(); i++) {
        // some assertions
        assert((*i)->getFromNode() == from);
        assert((*i)->getToNode() == to);
        // ad the number of lanes the current edge has
        nolanes += (*i)->getNumLanes();
        // build the id
        if (i != edges.begin()) {
            id += "+";
        }
        id += (*i)->getID();
        // compute the speed
        speed += (*i)->getSpeed();
        // build the priority
        priority = MAX2(priority, (*i)->getPriority());
    }
    speed /= edges.size();
    // build the new edge
    // @bug new edge does not know about allowed vclass of old edges
    // @bug both the width and the offset are not regarded
    NBEdge* newEdge = new NBEdge(id, from, to, "", speed, nolanes, priority,
                                 NBEdge::UNSPECIFIED_WIDTH, NBEdge::UNSPECIFIED_OFFSET,
                                 tpledge->getStreetName(), tpledge->myLaneSpreadFunction);
    insert(newEdge, true);
    // replace old edge by current within the nodes
    //  and delete the old
    from->replaceOutgoing(edges, newEdge);
    to->replaceIncoming(edges, newEdge);
    // patch connections
    //  add edge2edge-information
    for (i = edges.begin(); i != edges.end(); i++) {
        EdgeVector ev = (*i)->getConnectedEdges();
        for (EdgeVector::iterator j = ev.begin(); j != ev.end(); j++) {
            newEdge->addEdge2EdgeConnection(*j);
        }
    }
    //  move lane2lane-connections
    unsigned int currLane = 0;
    for (i = edges.begin(); i != edges.end(); i++) {
        newEdge->moveOutgoingConnectionsFrom(*i, currLane);
        currLane += (*i)->getNumLanes();
    }
    // patch tl-information
    currLane = 0;
    for (i = edges.begin(); i != edges.end(); i++) {
        unsigned int noLanes = (*i)->getNumLanes();
        for (unsigned int j = 0; j < noLanes; j++, currLane++) {
            // replace in traffic lights
            tlc.replaceRemoved(*i, j, newEdge, currLane);
        }
    }
    // delete joined edges
    for (i = edges.begin(); i != edges.end(); i++) {
        erase(dc, *i);
    }
}
コード例 #19
0
void
NBNodeCont::joinNodeClusters(NodeClusters clusters,
                             NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tlc) {
    for (NodeClusters::iterator i = clusters.begin(); i != clusters.end(); ++i) {
        std::set<NBNode*> cluster = *i;
        assert(cluster.size() > 1);
        Position pos;
        bool setTL;
        std::string id;
        TrafficLightType type;
        analyzeCluster(cluster, id, pos, setTL, type);
        if (!insert(id, pos)) {
            // should not fail
            WRITE_WARNING("Could not join junctions " + id);
            continue;
        }
        NBNode* newNode = retrieve(id);
        if (setTL) {
            NBTrafficLightDefinition* tlDef = new NBOwnTLDef(id, newNode, 0, type);
            if (!tlc.insert(tlDef)) {
                // actually, nothing should fail here
                delete tlDef;
                throw ProcessError("Could not allocate tls '" + id + "'.");
            }
        }
        // collect edges
        std::set<NBEdge*> allEdges;
        for (std::set<NBNode*>::const_iterator j = cluster.begin(); j != cluster.end(); ++j) {
            const EdgeVector& edges = (*j)->getEdges();
            allEdges.insert(edges.begin(), edges.end());
        }

        // remap and remove edges which are completely within the new intersection
        for (std::set<NBEdge*>::iterator j = allEdges.begin(); j != allEdges.end();) {
            NBEdge* e = (*j);
            NBNode* from = e->getFromNode();
            NBNode* to = e->getToNode();
            if (cluster.count(from) > 0 && cluster.count(to) > 0) {
                for (std::set<NBEdge*>::iterator l = allEdges.begin(); l != allEdges.end(); ++l) {
                    if (e != *l) {
                        (*l)->replaceInConnections(e, e->getConnections());
                    }
                }
                ec.erase(dc, e);
                allEdges.erase(j++); // erase does not invalidate the other iterators
            } else {
                ++j;
            }
        }

        // remap edges which are incoming / outgoing
        for (std::set<NBEdge*>::iterator j = allEdges.begin(); j != allEdges.end(); ++j) {
            NBEdge* e = (*j);
            std::vector<NBEdge::Connection> conns = e->getConnections();
            const bool outgoing = cluster.count(e->getFromNode()) > 0;
            NBNode* from = outgoing ? newNode : e->getFromNode();
            NBNode* to   = outgoing ? e->getToNode() : newNode;
            e->reinitNodes(from, to);
            // re-add connections which previously existed and may still valid.
            // connections to removed edges will be ignored
            for (std::vector<NBEdge::Connection>::iterator k = conns.begin(); k != conns.end(); ++k) {
                e->addLane2LaneConnection((*k).fromLane, (*k).toEdge, (*k).toLane, NBEdge::L2L_USER, false, (*k).mayDefinitelyPass);
            }
        }
        // remove original nodes
        registerJoinedCluster(cluster);
        for (std::set<NBNode*>::const_iterator j = cluster.begin(); j != cluster.end(); ++j) {
            erase(*j);
        }
    }
}
コード例 #20
0
unsigned int
NBNodeCont::joinJunctions(SUMOReal maxdist, NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tlc) {
    NodeClusters cands;
    NodeClusters clusters;
    generateNodeClusters(maxdist, cands);
    for (NodeClusters::iterator i = cands.begin(); i != cands.end(); ++i) {
        std::set<NBNode*> cluster = (*i);
        // remove join exclusions
        for (std::set<NBNode*>::iterator j = cluster.begin(); j != cluster.end();) {
            std::set<NBNode*>::iterator check = j;
            ++j;
            if (myJoinExclusions.count((*check)->getID()) > 0) {
                cluster.erase(check);
            }
        }
        // iteratively remove the fringe
        bool pruneFringe = true;
        while (pruneFringe) {
            pruneFringe = false;
            for (std::set<NBNode*>::iterator j = cluster.begin(); j != cluster.end();) {
                std::set<NBNode*>::iterator check = j;
                NBNode* n = *check;
                ++j;
                // remove nodes with degree <= 2 at fringe of the cluster (at least one edge leads to a non-cluster node)
                if (
                    (n->getIncomingEdges().size() <= 1 && n->getOutgoingEdges().size() <= 1) &&
                    ((n->getIncomingEdges().size() == 0 ||
                      (n->getIncomingEdges().size() == 1 && cluster.count(n->getIncomingEdges()[0]->getFromNode()) == 0)) ||
                     (n->getOutgoingEdges().size() == 0 ||
                      (n->getOutgoingEdges().size() == 1 && cluster.count(n->getOutgoingEdges()[0]->getToNode()) == 0)))
                ) {
                    cluster.erase(check);
                    pruneFringe = true; // other nodes could belong to the fringe now
                }
            }
        }
        if (cluster.size() > 1) {
            // check for clusters which are to complex and probably won't work very well
            // we count the incoming edges of the final junction
            std::set<NBEdge*> finalIncoming;
            std::vector<std::string> nodeIDs;
            for (std::set<NBNode*>::const_iterator j = cluster.begin(); j != cluster.end(); ++j) {
                nodeIDs.push_back((*j)->getID());
                const EdgeVector& edges = (*j)->getIncomingEdges();
                for (EdgeVector::const_iterator it_edge = edges.begin(); it_edge != edges.end(); ++it_edge) {
                    NBEdge* edge = *it_edge;
                    if (cluster.count(edge->getFromNode()) == 0) {
                        // incoming edge, does not originate in the cluster
                        finalIncoming.insert(edge);
                    }
                }

            }
            if (finalIncoming.size() > 4) {
                WRITE_WARNING("Not joining junctions " + joinToString(nodeIDs, ',') + " because the cluster is too complex");
            } else {
                clusters.push_back(cluster);
            }
        }
    }
    joinNodeClusters(clusters, dc, ec, tlc);
    return (int)clusters.size();
}
コード例 #21
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);
        }
    }
}
コード例 #22
0
void
NBTurningDirectionsComputer::computeTurnDirectionsForNode(NBNode* node) {
    const std::vector<NBEdge*>& incoming = node->getIncomingEdges();
    const std::vector<NBEdge*>& outgoing = node->getOutgoingEdges();
    std::vector<Combination> combinations;
    for (std::vector<NBEdge*>::const_iterator j = outgoing.begin(); j != outgoing.end(); ++j) {
        NBEdge* outedge = *j;
        for (std::vector<NBEdge*>::const_iterator k = incoming.begin(); k != incoming.end(); ++k) {
            NBEdge* e = *k;
            if (e->getConnections().size() != 0 && !e->isConnectedTo(outedge)) {
                // has connections, but not to outedge; outedge will not be the turn direction
                //
                // @todo: this seems to be needed due to legacy issues; actually, we could regard
                //  such pairs, too, and it probably would increase the accuracy. But there is
                //  no mechanism implemented, yet, which would avoid adding them as turnarounds though
                //  no connection is specified.
                continue;
            }

            // @todo: check whether NBHelpers::relAngle is properly defined and whether it should really be used, here
            SUMOReal angle = fabs(NBHelpers::relAngle(e->getAngleAtNode(node), outedge->getAngleAtNode(node)));
            if (angle < 160) {
                continue;
            }
            if (e->getFromNode() == outedge->getToNode()) {
                // they connect the same nodes; should be the turnaround direction
                // we'll assign a maximum number
                //
                // @todo: indeed, we have observed some pathological intersections
                //  see "294831560" in OSM/adlershof. Here, several edges are connecting
                //  same nodes. We have to do the angle check before...
                //
                // @todo: and well, there are some other as well, see plain import
                //  of delphi_muenchen (elmar), intersection "59534191". Not that it would
                //  be realistic in any means; we will warn, here.
                angle += 360;
            }
            Combination c;
            c.from = e;
            c.to = outedge;
            c.angle = angle;
            combinations.push_back(c);
        }
    }
    // sort combinations so that the ones with the highest angle are at the begin
    std::sort(combinations.begin(), combinations.end(), combination_by_angle_sorter());
    std::set<NBEdge*> seen;
    bool haveWarned = false;
    for (std::vector<Combination>::const_iterator j = combinations.begin(); j != combinations.end(); ++j) {
        if (seen.find((*j).from) != seen.end() || seen.find((*j).to) != seen.end()) {
            // do not regard already set edges
            if ((*j).angle > 360 && !haveWarned) {
                WRITE_WARNING("Ambiguity in turnarounds computation at node '" + node->getID() + "'.");
                haveWarned = true;
            }
            continue;
        }
        // mark as seen
        seen.insert((*j).from);
        seen.insert((*j).to);
        // set turnaround information
        (*j).from->setTurningDestination((*j).to);
    }
}
コード例 #23
0
ファイル: NIVissimDisturbance.cpp プロジェクト: behrisch/sumo
bool
NIVissimDisturbance::addToNode(NBNode* node, NBDistrictCont& dc,
                               NBNodeCont& nc, NBEdgeCont& ec) {
    myNode = 0;
    NIVissimConnection* pc =
        NIVissimConnection::dictionary(myEdge.getEdgeID());
    NIVissimConnection* bc =
        NIVissimConnection::dictionary(myDisturbance.getEdgeID());
    if (pc == nullptr && bc == nullptr) {
        // This has not been tested completely, yet
        // Both competing abstract edges are normal edges
        // We have to find a crossing point, build a node here,
        //  split both edges and add the connections
        NIVissimEdge* e1 = NIVissimEdge::dictionary(myEdge.getEdgeID());
        NIVissimEdge* e2 = NIVissimEdge::dictionary(myDisturbance.getEdgeID());
        WRITE_WARNING("Ugly split to prohibit '" + toString<int>(e1->getID()) + "' by '" + toString<int>(e2->getID()) + "'.");
        Position pos = e1->crossesEdgeAtPoint(e2);
        std::string id1 = toString<int>(e1->getID()) + "x" + toString<int>(e2->getID());
        std::string id2 = toString<int>(e2->getID()) + "x" + toString<int>(e1->getID());
        NBNode* node1 = nc.retrieve(id1);
        NBNode* node2 = nc.retrieve(id2);
        NBNode* node = nullptr;
        assert(node1 == 0 || node2 == 0);
        if (node1 == nullptr && node2 == nullptr) {
            refusedProhibits++;
            return false;
            /*            node = new NBNode(id1, pos.x(), pos.y(), "priority");
                        if(!myNodeCont.insert(node)) {
                             "nope, NIVissimDisturbance" << endl;
                            throw 1;
                        }*/
        } else {
            node = node1 == nullptr ? node2 : node1;
        }
        ec.splitAt(dc, ec.retrievePossiblySplit(toString<int>(e1->getID()), myEdge.getPosition()), node);
        ec.splitAt(dc, ec.retrievePossiblySplit(toString<int>(e2->getID()), myDisturbance.getPosition()), node);
        // !!! in some cases, one of the edges is not being build because it's too short
        // !!! what to do in these cases?
        NBEdge* mayDriveFrom = ec.retrieve(toString<int>(e1->getID()) + "[0]");
        NBEdge* mayDriveTo = ec.retrieve(toString<int>(e1->getID()) + "[1]");
        NBEdge* mustStopFrom = ec.retrieve(toString<int>(e2->getID()) + "[0]");
        NBEdge* mustStopTo = ec.retrieve(toString<int>(e2->getID()) + "[1]");
        if (mayDriveFrom != nullptr && mayDriveTo != nullptr && mustStopFrom != nullptr && mustStopTo != nullptr) {
            node->addSortedLinkFoes(
                NBConnection(mayDriveFrom, mayDriveTo),
                NBConnection(mayDriveFrom, mayDriveTo));
        } else {
            refusedProhibits++;
            return false;
            // !!! warning
        }
//        }
    } else if (pc != nullptr && bc == nullptr) {
        // The prohibited abstract edge is a connection, the other
        //  is not;
        // The connection will be prohibitesd by all connections
        //  outgoing from the "real" edge

        NBEdge* e = ec.retrievePossiblySplit(toString<int>(myDisturbance.getEdgeID()), myDisturbance.getPosition());
        if (e == nullptr) {
            WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID()) + "'. Have not found disturbance.");
            refusedProhibits++;
            return false;
        }
        if (e->getFromNode() == e->getToNode()) {
            WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID()) + "'. Disturbance connects same node.");
            refusedProhibits++;
            // What to do with self-looping edges?
            return false;
        }
        // get the begin of the prohibited connection
        std::string id_pcoe = toString<int>(pc->getFromEdgeID());
        std::string id_pcie = toString<int>(pc->getToEdgeID());
        NBEdge* pcoe = ec.retrievePossiblySplit(id_pcoe, id_pcie, true);
        NBEdge* pcie = ec.retrievePossiblySplit(id_pcie, id_pcoe, false);
        // check whether it's ending node is the node the prohibited
        //  edge end at
        if (pcoe != nullptr && pcie != nullptr && pcoe->getToNode() == e->getToNode()) {
            // if so, simply prohibit the connections
            NBNode* node = e->getToNode();
            const EdgeVector& connected = e->getConnectedEdges();
            for (EdgeVector::const_iterator i = connected.begin(); i != connected.end(); i++) {
                node->addSortedLinkFoes(
                    NBConnection(e, *i),
                    NBConnection(pcoe, pcie));
            }
        } else {
            WRITE_WARNING("Would have to split edge '" + e->getID() + "' to build a prohibition");
            refusedProhibits++;
            // quite ugly - why was it not build?
            return false;
            /*
            std::string nid1 = e->getID() + "[0]";
            std::string nid2 = e->getID() + "[1]";

            if(ec.splitAt(e, node)) {
                node->addSortedLinkFoes(
                        NBConnection(
                            ec.retrieve(nid1),
                            ec.retrieve(nid2)
                        ),
                        getConnection(node, myEdge.getEdgeID())
                    );
            }
            */
        }
    } else if (bc != nullptr && pc == nullptr) {
        // The prohibiting abstract edge is a connection, the other
        //  is not;
        // We have to split the other one and add the prohibition
        //  description

        NBEdge* e = ec.retrievePossiblySplit(toString<int>(myEdge.getEdgeID()), myEdge.getPosition());
        if (e == nullptr) {
            WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' - it was not built.");
            return false;
        }
        std::string nid1 = e->getID() + "[0]";
        std::string nid2 = e->getID() + "[1]";
        if (e->getFromNode() == e->getToNode()) {
            WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID()) + "'.");
            refusedProhibits++;
            // What to do with self-looping edges?
            return false;
        }
        // get the begin of the prohibiting connection
        std::string id_bcoe = toString<int>(bc->getFromEdgeID());
        std::string id_bcie = toString<int>(bc->getToEdgeID());
        NBEdge* bcoe = ec.retrievePossiblySplit(id_bcoe, id_bcie, true);
        NBEdge* bcie = ec.retrievePossiblySplit(id_bcie, id_bcoe, false);
        // check whether it's ending node is the node the prohibited
        //  edge end at
        if (bcoe != nullptr && bcie != nullptr && bcoe->getToNode() == e->getToNode()) {
            // if so, simply prohibit the connections
            NBNode* node = e->getToNode();
            const EdgeVector& connected = e->getConnectedEdges();
            for (EdgeVector::const_iterator i = connected.begin(); i != connected.end(); i++) {
                node->addSortedLinkFoes(
                    NBConnection(bcoe, bcie),
                    NBConnection(e, *i));
            }
        } else {
            WRITE_WARNING("Would have to split edge '" + e->getID() + "' to build a prohibition");
            refusedProhibits++;
            return false;
            /*
            // quite ugly - why was it not build?
            if(ec.splitAt(e, node)) {
                node->addSortedLinkFoes(
                        getConnection(node, myDisturbance.getEdgeID()),
                        NBConnection(
                            ec.retrieve(nid1),
                            ec.retrieve(nid2)
                        )
                    );
            }
            */
        }
    } else {
        // both the prohibiting and the prohibited abstract edges
        //  are connections
        // We can retrieve the conected edges and add the desription
        NBConnection conn1 = getConnection(node, myDisturbance.getEdgeID());
        NBConnection conn2 = getConnection(node, myEdge.getEdgeID());
        if (!conn1.check(ec) || !conn2.check(ec)) {
            refusedProhibits++;
            return false;
        }
        node->addSortedLinkFoes(conn1, conn2);
    }
    return true;
}
コード例 #24
0
ファイル: NWWriter_XML.cpp プロジェクト: harora/ITS
void
NWWriter_XML::writeEdgesAndConnections(const OptionsCont& oc, NBNodeCont& nc, NBEdgeCont& ec) {
    const GeoConvHelper& gch = GeoConvHelper::getFinal();
    bool useGeo = oc.exists("proj.plain-geo") && oc.getBool("proj.plain-geo");
    const bool geoAccuracy = useGeo || gch.usingInverseGeoProjection();

    OutputDevice& edevice = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".edg.xml");
    edevice.writeXMLHeader("edges", NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/edges_file.xsd\"");
    OutputDevice& cdevice = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".con.xml");
    cdevice.writeXMLHeader("connections", NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/connections_file.xsd\"");
    bool noNames = !oc.getBool("output.street-names");
    for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) {
        // write the edge itself to the edges-files
        NBEdge* e = (*i).second;
        edevice.openTag(SUMO_TAG_EDGE);
        edevice.writeAttr(SUMO_ATTR_ID, e->getID());
        edevice.writeAttr(SUMO_ATTR_FROM, e->getFromNode()->getID());
        edevice.writeAttr(SUMO_ATTR_TO, e->getToNode()->getID());
        if (!noNames && e->getStreetName() != "") {
            edevice.writeAttr(SUMO_ATTR_NAME, StringUtils::escapeXML(e->getStreetName()));
        }
        edevice.writeAttr(SUMO_ATTR_PRIORITY, e->getPriority());
        // write the type if given
        if (e->getTypeID() != "") {
            edevice.writeAttr(SUMO_ATTR_TYPE, e->getTypeID());
        }
        edevice.writeAttr(SUMO_ATTR_NUMLANES, e->getNumLanes());
        if (!e->hasLaneSpecificSpeed()) {
            edevice.writeAttr(SUMO_ATTR_SPEED, e->getSpeed());
        }
        // write non-default geometry
        if (!e->hasDefaultGeometry()) {
            PositionVector geom = e->getGeometry();
            if (useGeo) {
                for (int i = 0; i < (int) geom.size(); i++) {
                    gch.cartesian2geo(geom[i]);
                }
            }
            if (geoAccuracy) {
                edevice.setPrecision(GEO_OUTPUT_ACCURACY);
            }
            edevice.writeAttr(SUMO_ATTR_SHAPE, geom);
            if (geoAccuracy) {
                edevice.setPrecision();
            }
        }
        // write the spread type if not default ("right")
        if (e->getLaneSpreadFunction() != LANESPREAD_RIGHT) {
            edevice.writeAttr(SUMO_ATTR_SPREADTYPE, toString(e->getLaneSpreadFunction()));
        }
        // write the length if it was specified
        if (e->hasLoadedLength()) {
            edevice.writeAttr(SUMO_ATTR_LENGTH, e->getLoadedLength());
        }
        // some attributes can be set by edge default or per lane. Write as default if possible (efficiency)
        if (e->getLaneWidth() != NBEdge::UNSPECIFIED_WIDTH && !e->hasLaneSpecificWidth()) {
            edevice.writeAttr(SUMO_ATTR_WIDTH, e->getLaneWidth());
        }
        if (e->getOffset() != NBEdge::UNSPECIFIED_OFFSET && !e->hasLaneSpecificOffset()) {
            edevice.writeAttr(SUMO_ATTR_OFFSET, e->getOffset());
        }
        if (!e->needsLaneSpecificOutput()) {
            edevice.closeTag();
        } else {
            for (unsigned int i = 0; i < e->getLanes().size(); ++i) {
                const NBEdge::Lane& lane = e->getLanes()[i];
                edevice.openTag(SUMO_TAG_LANE);
                edevice.writeAttr(SUMO_ATTR_INDEX, i);
                // write allowed lanes
                NWWriter_SUMO::writePermissions(edevice, lane.permissions);
                NWWriter_SUMO::writePreferences(edevice, lane.preferred);
                // write other attributes
                if (lane.width != NBEdge::UNSPECIFIED_WIDTH && e->hasLaneSpecificWidth()) {
                    edevice.writeAttr(SUMO_ATTR_WIDTH, lane.width);
                }
                if (lane.offset != NBEdge::UNSPECIFIED_OFFSET && e->hasLaneSpecificOffset()) {
                    edevice.writeAttr(SUMO_ATTR_OFFSET, lane.offset);
                }
                if (e->hasLaneSpecificSpeed()) {
                    edevice.writeAttr(SUMO_ATTR_SPEED, lane.speed);
                }
                edevice.closeTag();
            }
            edevice.closeTag();
        }
        // write this edge's connections to the connections-files
        e->sortOutgoingConnectionsByIndex();
        const std::vector<NBEdge::Connection> connections = e->getConnections();
        for (std::vector<NBEdge::Connection>::const_iterator c = connections.begin(); c != connections.end(); ++c) {
            NWWriter_SUMO::writeConnection(cdevice, *e, *c, false, NWWriter_SUMO::PLAIN);
        }
        if (connections.size() > 0) {
            cdevice << "\n";
        }
    }

    // write loaded prohibitions to the connections-file
    for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
        NWWriter_SUMO::writeProhibitions(cdevice, i->second->getProhibitions());
    }
    edevice.close();
    cdevice.close();
}