NBEdge* NBEdgeCont::retrievePossiblySplit(const std::string& id, const std::string& hint, bool incoming) const { // try to retrieve using the given name (iterative) NBEdge* edge = retrieve(id); if (edge != 0) { return edge; } // now, we did not find it; we have to look over all possibilities EdgeVector hints; // check whether at least the hint was not splitted NBEdge* hintedge = retrieve(hint); if (hintedge == 0) { hints = getGeneratedFrom(hint); } else { hints.push_back(hintedge); } EdgeVector candidates = getGeneratedFrom(id); for (EdgeVector::iterator i = hints.begin(); i != hints.end(); i++) { NBEdge* hintedge = (*i); for (EdgeVector::iterator j = candidates.begin(); j != candidates.end(); j++) { NBEdge* poss_searched = (*j); NBNode* node = incoming ? poss_searched->myTo : poss_searched->myFrom; const EdgeVector& cont = incoming ? node->getOutgoingEdges() : node->getIncomingEdges(); if (find(cont.begin(), cont.end(), hintedge) != cont.end()) { return poss_searched; } } } return 0; }
SUMOReal NBContHelper::maxSpeed(const EdgeVector& ev) { assert(ev.size() > 0); SUMOReal max = (*(ev.begin()))->getSpeed(); for (EdgeVector::const_iterator i = ev.begin() + 1; i != ev.end(); i++) { max = max > (*i)->getSpeed() ? max : (*i)->getSpeed(); } return max; }
SUMOReal NBContHelper::getMinSpeed(const EdgeVector& edges) { if (edges.size() == 0) { return -1; } SUMOReal ret = (*(edges.begin()))->getSpeed(); for (EdgeVector::const_iterator i = edges.begin() + 1; i != edges.end(); i++) { if ((*i)->getSpeed() < ret) { ret = (*i)->getSpeed(); } } return ret; }
double NBContHelper::getMaxSpeed(const EdgeVector& edges) { if (edges.size() == 0) { return -1; } double ret = (*(edges.begin()))->getSpeed(); for (EdgeVector::const_iterator i = edges.begin() + 1; i != edges.end(); i++) { if ((*i)->getSpeed() > ret) { ret = (*i)->getSpeed(); } } return ret; }
bool GNECrossing::isValid(SumoXMLAttr key, const std::string& value) { auto crossing = myParentJunction->getNBNode()->getCrossing(myCrossingEdges); switch (key) { case SUMO_ATTR_ID: return false; case SUMO_ATTR_EDGES: if (canParse<std::vector<GNEEdge*> >(myNet, value, false)) { // parse edges and save their IDs in a set std::vector<GNEEdge*> parsedEdges = parse<std::vector<GNEEdge*> >(myNet, value); EdgeVector nbEdges; for (auto i : parsedEdges) { nbEdges.push_back(i->getNBEdge()); } std::sort(nbEdges.begin(), nbEdges.end()); // EdgeVector originalEdges = crossing->edges; std::sort(originalEdges.begin(), originalEdges.end()); // return true if we're setting the same edges if (toString(nbEdges) == toString(originalEdges)) { return true; } else { return !myParentJunction->getNBNode()->checkCrossingDuplicated(nbEdges); } } else { return false; } case SUMO_ATTR_WIDTH: return canParse<double>(value) && ((parse<double>(value) > 0) || (parse<double>(value) == -1)); // kann NICHT 0 sein, oder -1 (bedeutet default) case SUMO_ATTR_PRIORITY: return canParse<bool>(value); case SUMO_ATTR_TLLINKINDEX: case SUMO_ATTR_TLLINKINDEX2: return (crossing->tlID != "" && canParse<int>(value) // -1 means that tlLinkIndex2 takes on the same value as tlLinkIndex when setting idnices && ((parse<double>(value) >= 0) || ((parse<double>(value) == -1) && (key == SUMO_ATTR_TLLINKINDEX2))) && myParentJunction->getNBNode()->getControllingTLS().size() > 0 && (*myParentJunction->getNBNode()->getControllingTLS().begin())->getMaxValidIndex() >= parse<int>(value)); case SUMO_ATTR_CUSTOMSHAPE: { // empty shapes are allowed return canParse<PositionVector>(value); } case GNE_ATTR_SELECTED: return canParse<bool>(value); case GNE_ATTR_GENERIC: return isGenericParametersValid(value); default: throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'"); } }
RealType bottleneck_distance(const Diagram1& dgm1, const Diagram2& dgm2, const Norm& norm) { typedef typename Diagram1::const_iterator Citer1; typedef typename Diagram2::const_iterator Citer2; const unsigned max_size = dgm1.size() + dgm2.size(); // Compute all the edges and sort them by distance EdgeVector edges; // Connect all diagonal points to each other for (unsigned i = dgm1.size(); i < max_size; ++i) for (unsigned j = max_size + dgm2.size(); j < 2*max_size; ++j) edges.push_back(Edge(i, j, 0)); // Edges between real points unsigned i = 0; for (Citer1 cur1 = dgm1.begin(); cur1 != dgm1.end(); ++cur1) { unsigned j = max_size; for (Citer2 cur2 = dgm2.begin(); cur2 != dgm2.end(); ++cur2) edges.push_back(Edge(i,j++, norm(*cur1, *cur2))); ++i; } // Edges between real points and their corresponding diagonal points i = 0; for (Citer1 cur1 = dgm1.begin(); cur1 != dgm1.end(); ++cur1, ++i) edges.push_back(Edge(i, max_size + dgm2.size() + i, norm.diagonal(*cur1))); i = max_size; for (Citer2 cur2 = dgm2.begin(); cur2 != dgm2.end(); ++cur2, ++i) edges.push_back(Edge(dgm1.size() + (i - max_size), i, norm.diagonal(*cur2))); std::sort(edges.begin(), edges.end()); //for (i = 0; i < edges.size(); ++i) // std::cout << "Edge: " << edges[i].first << " " << edges[i].second << " " << edges[i].distance << std::endl; // Perform cardinality based binary search typedef boost::counting_iterator<EV_const_iterator> EV_counting_const_iterator; EV_counting_const_iterator bdistance = std::upper_bound(EV_counting_const_iterator(edges.begin()), EV_counting_const_iterator(edges.end()), edges.begin(), CardinaliyComparison(max_size, edges.begin())); return (*bdistance)->distance; }
void GNENet::joinSelectedJunctions(GNEUndoList* undoList) { std::vector<GNEJunction*> selected = retrieveJunctions(true); if (selected.size() < 2) { return; } undoList->p_begin("Join selected junctions"); EdgeVector allIncoming; EdgeVector allOutgoing; std::set<NBNode*> cluster; for (std::vector<GNEJunction*>::iterator it = selected.begin(); it != selected.end(); it++) { cluster.insert((*it)->getNBNode()); const EdgeVector& incoming = (*it)->getNBNode()->getIncomingEdges(); allIncoming.insert(allIncoming.end(), incoming.begin(), incoming.end()); const EdgeVector& outgoing = (*it)->getNBNode()->getOutgoingEdges(); allOutgoing.insert(allOutgoing.end(), outgoing.begin(), outgoing.end()); } // create new junction Position pos; bool setTL; std::string id; TrafficLightType type; myNetBuilder->getNodeCont().analyzeCluster(cluster, id, pos, setTL, type); // XXX this is not undone when calling 'undo' myNetBuilder->getNodeCont().registerJoinedCluster(cluster); GNEJunction* joined = createJunction(pos, undoList); if (setTL) { joined->setAttribute(SUMO_ATTR_TYPE, toString(NODETYPE_TRAFFIC_LIGHT), undoList); // XXX ticket831 //joined-><getTrafficLight>->setAttribute(SUMO_ATTR_TYPE, toString(type), undoList); } // remap edges for (EdgeVector::const_iterator it = allIncoming.begin(); it != allIncoming.end(); it++) { GNEEdge* oldEdge = myEdges[(*it)->getID()]; remapEdge(oldEdge, oldEdge->getSource(), joined, undoList, true); } for (EdgeVector::const_iterator it = allOutgoing.begin(); it != allOutgoing.end(); it++) { GNEEdge* oldEdge = myEdges[(*it)->getID()]; remapEdge(oldEdge, joined, oldEdge->getDest(), undoList, true); } // delete original junctions for (std::vector<GNEJunction*>::iterator it = selected.begin(); it != selected.end(); it++) { deleteJunction(*it, undoList); } joined->setAttribute(SUMO_ATTR_ID, id, undoList); undoList->p_end(); }
std::pair<NBEdge*, NBEdge*> NBOwnTLDef::getBestCombination(const EdgeVector& edges) { std::pair<NBEdge*, NBEdge*> bestPair(static_cast<NBEdge*>(0), static_cast<NBEdge*>(0)); SUMOReal bestValue = -1; for (EdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) { for (EdgeVector::const_iterator j = i + 1; j != edges.end(); ++j) { const SUMOReal value = computeUnblockedWeightedStreamNumber(*i, *j); if (value > bestValue) { bestValue = value; bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j); } else if (value == bestValue) { const SUMOReal ca = GeomHelper::getMinAngleDiff((*i)->getAngleAtNode((*i)->getToNode()), (*j)->getAngleAtNode((*j)->getToNode())); const SUMOReal oa = GeomHelper::getMinAngleDiff(bestPair.first->getAngleAtNode(bestPair.first->getToNode()), bestPair.second->getAngleAtNode(bestPair.second->getToNode())); if (fabs(oa - ca) < NUMERICAL_EPS) { // break ties by id if (bestPair.first->getID() < (*i)->getID()) { bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j); } } else if (oa < ca) { bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j); } } } } return bestPair; }
void GNEJunction::setLogicValid(bool valid, GNEUndoList* undoList, const std::string& status) { myHasValidLogic = valid; if (!valid) { assert(undoList != 0); assert(undoList->hasCommandGroup()); undoList->add(new GNEChange_Attribute(this, GNE_ATTR_MODIFICATION_STATUS, status)); // allow edges to recompute their connections NBTurningDirectionsComputer::computeTurnDirectionsForNode(&myNBNode, false); EdgeVector incoming = EdgeVector(myNBNode.getIncomingEdges()); for (EdgeVector::iterator it = incoming.begin(); it != incoming.end(); it++) { NBEdge* srcNBE = *it; NBEdge* turnEdge = srcNBE->getTurnDestination(); GNEEdge* srcEdge = myNet->retrieveEdge(srcNBE->getID()); std::vector<NBEdge::Connection> connections = srcNBE->getConnections(); // make a copy! // delete in reverse so that undoing will add connections in the original order for (std::vector<NBEdge::Connection>::reverse_iterator con_it = connections.rbegin(); con_it != connections.rend(); con_it++) { bool hasTurn = con_it->toEdge == turnEdge; undoList->add(new GNEChange_Connection( srcEdge, con_it->fromLane, con_it->toEdge->getID(), con_it->toLane, con_it->mayDefinitelyPass, false), true); // needs to come after GNEChange_Connection // XXX bug: this code path will not be used on a redo! if (hasTurn) { myNet->addExplicitTurnaround(srcNBE->getID()); } } undoList->add(new GNEChange_Attribute(srcEdge, GNE_ATTR_MODIFICATION_STATUS, status), true); } invalidateTLS(undoList); } else { rebuildCrossings(false); } }
void NGNet::toNB() const { std::vector<NBNode*> nodes; for (NGNodeList::const_iterator i1 = myNodeList.begin(); i1 != myNodeList.end(); i1++) { NBNode* node = (*i1)->buildNBNode(myNetBuilder); nodes.push_back(node); myNetBuilder.getNodeCont().insert(node); } for (NGEdgeList::const_iterator i2 = myEdgeList.begin(); i2 != myEdgeList.end(); i2++) { NBEdge* edge = (*i2)->buildNBEdge(myNetBuilder); myNetBuilder.getEdgeCont().insert(edge); } // now, let's append the reverse directions... SUMOReal bidiProb = OptionsCont::getOptions().getFloat("rand.bidi-probability"); for (std::vector<NBNode*>::const_iterator i = nodes.begin(); i != nodes.end(); ++i) { NBNode* node = *i; EdgeVector incoming = node->getIncomingEdges(); for (EdgeVector::const_iterator j = incoming.begin(); j != incoming.end(); ++j) { if (node->getConnectionTo((*j)->getFromNode()) == 0 && RandHelper::rand() <= bidiProb) { NBEdge* back = new NBEdge("-" + (*j)->getID(), node, (*j)->getFromNode(), "", myNetBuilder.getTypeCont().getSpeed(""), myNetBuilder.getTypeCont().getNumLanes(""), myNetBuilder.getTypeCont().getPriority(""), myNetBuilder.getTypeCont().getWidth(""), NBEdge::UNSPECIFIED_OFFSET); myNetBuilder.getEdgeCont().insert(back); } } } }
/* ------------------------------------------------------------------------- * utility methods * ----------------------------------------------------------------------- */ void NBContHelper::nextCW(const EdgeVector& edges, EdgeVector::const_iterator& from) { from++; if (from == edges.end()) { from = edges.begin(); } }
void NBDistrict::replaceOutgoing(const EdgeVector& which, NBEdge* const by) { // temporary structures EdgeVector newList; WeightsCont newWeights; SUMOReal joinedVal = 0; // go through the list of sinks EdgeVector::iterator i = mySources.begin(); WeightsCont::iterator j = mySourceWeights.begin(); for (; i != mySources.end(); i++, j++) { NBEdge* tmp = (*i); SUMOReal val = (*j); if (find(which.begin(), which.end(), tmp) == which.end()) { // if the current edge shall not be replaced, add to the // temporary list newList.push_back(tmp); newWeights.push_back(val); } else { // otherwise, skip it and add its weight to the one to be inserted // instead joinedVal += val; } } // add the one to be inserted instead newList.push_back(by); newWeights.push_back(joinedVal); // assign to values mySources = newList; mySourceWeights = newWeights; }
long GNEConnectorFrame::onCmdSelectConflicts(FXObject*, FXSelector, void*) { std::vector<GUIGlID> selectIDs; // conflicts happen per edge so we can look at each edge in isolation const std::vector<GNEEdge*> edges = myViewNet->getNet()->retrieveEdges(); for (std::vector<GNEEdge*>::const_iterator edge_it = edges.begin(); edge_it != edges.end(); edge_it++) { NBEdge* nbe = (*edge_it)->getNBEdge(); const EdgeVector destinations = nbe->getConnectedEdges(); const std::vector<NBEdge::Connection>& connections = nbe->getConnections(); for (EdgeVector::const_iterator dest_it = destinations.begin(); dest_it != destinations.end(); dest_it++) { GNEEdge* dest = myViewNet->getNet()->retrieveEdge((*dest_it)->getID()); const GNEEdge::LaneVector& destLanes = dest->getLanes(); for (GNEEdge::LaneVector::const_iterator it_lane = destLanes.begin(); it_lane != destLanes.end(); it_lane++) { const bool isConflicted = count_if( connections.begin(), connections.end(), NBEdge::connections_toedgelane_finder(*dest_it, (int)(*it_lane)->getIndex(), -1)) > 1; if (isConflicted) { selectIDs.push_back((*it_lane)->getGlID()); } } } } myViewNet->getViewParent()->getSelectorFrame()->handleIDs(selectIDs, false, GNESelectorFrame::SET_REPLACE); return 1; }
void NBContHelper::nextCCW(const EdgeVector& edges, EdgeVector::const_iterator& from) { if (from == edges.begin()) { from = edges.end() - 1; } else { --from; } }
std::pair<NBEdge*, NBEdge*> NBOwnTLDef::getBestPair(EdgeVector& incoming) { if (incoming.size() == 1) { // only one there - return the one std::pair<NBEdge*, NBEdge*> ret(*incoming.begin(), static_cast<NBEdge*>(0)); incoming.clear(); return ret; } // determine the best combination // by priority, first EdgeVector used; std::sort(incoming.begin(), incoming.end(), edge_by_incoming_priority_sorter()); used.push_back(*incoming.begin()); // the first will definitely be used // get the ones with the same priority int prio = getToPrio(*used.begin()); for (EdgeVector::iterator i = incoming.begin() + 1; i != incoming.end() && prio != getToPrio(*i); ++i) { used.push_back(*i); } // if there only lower priorised, use these, too if (used.size() < 2) { used = incoming; } std::pair<NBEdge*, NBEdge*> ret = getBestCombination(used); incoming.erase(find(incoming.begin(), incoming.end(), ret.first)); incoming.erase(find(incoming.begin(), incoming.end(), ret.second)); return ret; }
void GNENet::mergeJunctions(GNEJunction* moved, GNEJunction* target, GNEUndoList* undoList) { undoList->p_begin("merge junctions"); // position of moved and target are probably a bit different (snap radius) moved->move(target->getNBNode()->getPosition()); // register the move with undolist (must happend within the undo group) moved->registerMove(undoList); // deleting edges changes in the underlying EdgeVector so we have to make a copy const EdgeVector incoming = moved->getNBNode()->getIncomingEdges(); for (EdgeVector::const_iterator it = incoming.begin(); it != incoming.end(); it++) { GNEEdge* oldEdge = myEdges[(*it)->getID()]; remapEdge(oldEdge, oldEdge->getSource(), target, undoList); } // deleting edges changes in the underlying EdgeVector so we have to make a copy const EdgeVector outgoing = moved->getNBNode()->getOutgoingEdges(); for (EdgeVector::const_iterator it = outgoing.begin(); it != outgoing.end(); it++) { GNEEdge* oldEdge = myEdges[(*it)->getID()]; remapEdge(oldEdge, target, oldEdge->getDest(), undoList); } deleteJunction(moved, undoList); undoList->p_end(); }
// ----- 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); } }
void NBTrafficLightDefinition::collectEdges() { myIncomingEdges.clear(); myEdgesWithin.clear(); EdgeVector myOutgoing; // collect the edges from the participating nodes for (std::vector<NBNode*>::iterator i = myControlledNodes.begin(); i != myControlledNodes.end(); i++) { const EdgeVector& incoming = (*i)->getIncomingEdges(); copy(incoming.begin(), incoming.end(), back_inserter(myIncomingEdges)); const EdgeVector& outgoing = (*i)->getOutgoingEdges(); copy(outgoing.begin(), outgoing.end(), back_inserter(myOutgoing)); } EdgeVector outer; // check which of the edges are completely within the junction // add them to the list of edges lying within the node for (EdgeVector::iterator j = myIncomingEdges.begin(); j != myIncomingEdges.end(); ++j) { NBEdge* edge = *j; // an edge lies within the logic if it is outgoing as well as incoming EdgeVector::iterator k = find(myOutgoing.begin(), myOutgoing.end(), edge); if (k != myOutgoing.end()) { myEdgesWithin.push_back(edge); } else { outer.push_back(edge); } } // collect edges that are reachable from the outside via controlled connections std::set<NBEdge*> reachable = collectReachable(outer, myEdgesWithin, true); // collect edges that are reachable from the outside regardless of controllability std::set<NBEdge*> reachable2 = collectReachable(outer, myEdgesWithin, false); const bool uncontrolledWithin = OptionsCont::getOptions().getBool("tls.uncontrolled-within"); for (EdgeVector::iterator j = myEdgesWithin.begin(); j != myEdgesWithin.end(); ++j) { NBEdge* edge = *j; // edges that are marked as 'inner' will not get their own phase when // computing traffic light logics (unless they cannot be reached from the outside at all) if (reachable.count(edge) == 1) { edge->setIsInnerEdge(); // legacy behavior if (uncontrolledWithin && myControlledInnerEdges.count(edge->getID()) == 0) { myIncomingEdges.erase(find(myIncomingEdges.begin(), myIncomingEdges.end(), edge)); } } if (reachable2.count(edge) == 0 && edge->getFirstNonPedestrianLaneIndex(NBNode::FORWARD, true) >= 0 && getID() != DummyID) { WRITE_WARNING("Unreachable edge '" + edge->getID() + "' within tlLogic '" + getID() + "'"); } } }
void NWWriter_SUMO::writeRoundabout(OutputDevice& into, const EdgeVector& r) { std::vector<std::string> edgeIDs; std::vector<std::string> nodeIDs; for (EdgeVector::const_iterator j = r.begin(); j != r.end(); ++j) { edgeIDs.push_back((*j)->getID()); nodeIDs.push_back((*j)->getToNode()->getID()); } // make output deterministic std::sort(edgeIDs.begin(), edgeIDs.end()); std::sort(nodeIDs.begin(), nodeIDs.end()); into.openTag(SUMO_TAG_ROUNDABOUT); into.writeAttr(SUMO_ATTR_NODES, joinToString(nodeIDs, " ")); into.writeAttr(SUMO_ATTR_EDGES, joinToString(edgeIDs, " ")); into.closeTag(); }
std::set<NBEdge*> NBTrafficLightDefinition::collectReachable(EdgeVector outer, const EdgeVector& within, bool checkControlled) { std::set<NBEdge*> reachable; while (outer.size() > 0) { NBEdge* from = outer.back(); outer.pop_back(); std::vector<NBEdge::Connection>& cons = from->getConnections(); for (std::vector<NBEdge::Connection>::iterator k = cons.begin(); k != cons.end(); k++) { NBEdge* to = (*k).toEdge; if (reachable.count(to) == 0 && (find(within.begin(), within.end(), to) != within.end()) && (!checkControlled || from->mayBeTLSControlled((*k).fromLane, to, (*k).toLane))) { reachable.insert(to); outer.push_back(to); } } } return reachable; }
void NBLoadedSUMOTLDef::collectEdges() { if (myControlledLinks.size() == 0) { NBTrafficLightDefinition::collectEdges(); } myIncomingEdges.clear(); EdgeVector myOutgoing; // collect the edges from the participating nodes for (std::vector<NBNode*>::iterator i = myControlledNodes.begin(); i != myControlledNodes.end(); i++) { const EdgeVector& incoming = (*i)->getIncomingEdges(); copy(incoming.begin(), incoming.end(), back_inserter(myIncomingEdges)); const EdgeVector& outgoing = (*i)->getOutgoingEdges(); copy(outgoing.begin(), outgoing.end(), back_inserter(myOutgoing)); } // check which of the edges are completely within the junction // and which are uncontrolled as well (we already know myControlledLinks) for (EdgeVector::iterator j = myIncomingEdges.begin(); j != myIncomingEdges.end();) { NBEdge* edge = *j; // an edge lies within the logic if it is outgoing as well as incoming EdgeVector::iterator k = find(myOutgoing.begin(), myOutgoing.end(), edge); if (k != myOutgoing.end()) { if (myControlledInnerEdges.count(edge->getID()) == 0) { bool controlled = false; for (NBConnectionVector::iterator it = myControlledLinks.begin(); it != myControlledLinks.end(); it++) { if ((*it).getFrom() == edge) { controlled = true; break; } } if (controlled) { myControlledInnerEdges.insert(edge->getID()); } else { myEdgesWithin.push_back(edge); (*j)->setIsInnerEdge(); ++j; //j = myIncomingEdges.erase(j); continue; } } } ++j; } }
void NBLoadedTLDef::SignalGroup::remapOutgoing(NBEdge* which, const EdgeVector& by) { NBConnectionVector newConns; for (NBConnectionVector::iterator i = myConnections.begin(); i != myConnections.end();) { if ((*i).getTo() == which) { NBConnection conn((*i).getFrom(), (*i).getTo()); i = myConnections.erase(i); for (EdgeVector::const_iterator j = by.begin(); j != by.end(); j++) { NBConnection curr(conn); if (!curr.replaceTo(which, *j)) { throw ProcessError("Could not replace edge '" + which->getID() + "' by '" + (*j)->getID() + "'.\nUndefined..."); } newConns.push_back(curr); } } else { i++; } } copy(newConns.begin(), newConns.end(), back_inserter(myConnections)); }
Edge* Node::deleteEdge(Node*node, NodeOrderType t) { EdgeVector tmpList; Edge* tmp; if(t == PREDECESSORS) tmpList = mInEdges; else tmpList = mOutEdges; EdgeVectorIterator edgeBegin = tmpList.begin(), edgeEnd = tmpList.end(); for(;edgeBegin != edgeEnd; edgeBegin++) { if(t == PREDECESSORS) { if((*edgeBegin)->getPred() == node) { tmp = (*edgeBegin); assert(tmp); tmpList.erase(edgeBegin); mInEdges = tmpList; mInMap.erase(mInMap.find(tmp->getPred())); mNumPredecessors--; return tmp; } } else if((*edgeBegin)->getSucc() == node) { tmp = (*edgeBegin); assert(tmp); tmpList.erase(edgeBegin); mOutEdges = tmpList; mOutMap.erase(mOutMap.find(tmp->getSucc())); mNumSuccessors--; return tmp; } } return 0; }
static void mergeBlocks(ir::IRKernel& k, ir::ControlFlowGraph::iterator predecessor, ir::ControlFlowGraph::iterator block) { typedef std::vector<ir::Edge> EdgeVector; // delete the branch at the end of the predecessor auto branch = getBranch(predecessor); if(branch != 0) { delete branch; predecessor->instructions.pop_back(); } // move remaining instructions intro the predecessor predecessor->instructions.insert(predecessor->instructions.end(), block->instructions.begin(), block->instructions.end()); block->instructions.clear(); // track the block's out edges EdgeVector outEdges; for(auto edge = block->out_edges.begin(); edge != block->out_edges.end(); ++edge) { outEdges.push_back(**edge); } // remove the block k.cfg()->remove_block(block); // add the edges back in for(auto edge = outEdges.begin(); edge != outEdges.end(); ++edge) { k.cfg()->insert_edge(ir::Edge(predecessor, edge->tail, edge->type)); } }
void GNENet::deleteJunction(GNEJunction* junction, GNEUndoList* undoList) { // we have to delete all incident edges because they cannot exist without that junction // all deletions must be undone/redone together so we start a new command group // @todo if any of those edges are dead-ends should we remove their orphan junctions as well? undoList->p_begin("delete junction"); // deleting edges changes in the underlying EdgeVector so we have to make a copy const EdgeVector incident = junction->getNBNode()->getEdges(); for (EdgeVector::const_iterator it = incident.begin(); it != incident.end(); it++) { deleteEdge(myEdges[(*it)->getID()], undoList); } // remove any traffic lights from the traffic light container (avoids lots of warnings) junction->setAttribute(SUMO_ATTR_TYPE, toString(NODETYPE_PRIORITY), undoList); undoList->add(new GNEChange_Junction(this, junction, false), true); if (gSelected.isSelected(GLO_JUNCTION, junction->getGlID())) { std::set<GUIGlID> deselected; deselected.insert(junction->getGlID()); undoList->add(new GNEChange_Selection(std::set<GUIGlID>(), deselected, true), true); } undoList->p_end(); }
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); } } }
NBTrafficLightLogic* NBOwnTLDef::myCompute(const NBEdgeCont&, unsigned int brakingTimeSeconds) { const SUMOTime brakingTime = TIME2STEPS(brakingTimeSeconds); const SUMOTime leftTurnTime = TIME2STEPS(6); // make configurable ? // build complete lists first const EdgeVector& incoming = getIncomingEdges(); EdgeVector fromEdges, toEdges; std::vector<bool> isLeftMoverV, isTurnaround; unsigned int noLanesAll = 0; unsigned int noLinksAll = 0; for (unsigned int i1 = 0; i1 < incoming.size(); i1++) { unsigned int noLanes = incoming[i1]->getNumLanes(); noLanesAll += noLanes; for (unsigned int i2 = 0; i2 < noLanes; i2++) { NBEdge* fromEdge = incoming[i1]; std::vector<NBEdge::Connection> approached = fromEdge->getConnectionsFromLane(i2); noLinksAll += (unsigned int) approached.size(); for (unsigned int i3 = 0; i3 < approached.size(); i3++) { if (!fromEdge->mayBeTLSControlled(i2, approached[i3].toEdge, approached[i3].toLane)) { --noLinksAll; continue; } assert(i3 < approached.size()); NBEdge* toEdge = approached[i3].toEdge; fromEdges.push_back(fromEdge); //myFromLanes.push_back(i2); toEdges.push_back(toEdge); if (toEdge != 0) { isLeftMoverV.push_back( isLeftMover(fromEdge, toEdge) || fromEdge->isTurningDirectionAt(fromEdge->getToNode(), toEdge)); isTurnaround.push_back( fromEdge->isTurningDirectionAt( fromEdge->getToNode(), toEdge)); } else { isLeftMoverV.push_back(true); isTurnaround.push_back(true); } } } } NBTrafficLightLogic* logic = new NBTrafficLightLogic(getID(), getProgramID(), noLinksAll, myOffset, myType); EdgeVector toProc = incoming; const SUMOTime greenTime = TIME2STEPS(OptionsCont::getOptions().getInt("tls.green.time")); // build all phases while (toProc.size() > 0) { std::pair<NBEdge*, NBEdge*> chosen; if (incoming.size() == 2) { chosen = std::pair<NBEdge*, NBEdge*>(toProc[0], static_cast<NBEdge*>(0)); toProc.erase(toProc.begin()); } else { chosen = getBestPair(toProc); } unsigned int pos = 0; std::string state((size_t) noLinksAll, 'o'); // plain straight movers for (unsigned int i1 = 0; i1 < (unsigned int) incoming.size(); ++i1) { NBEdge* fromEdge = incoming[i1]; const bool inChosen = fromEdge == chosen.first || fromEdge == chosen.second; //chosen.find(fromEdge)!=chosen.end(); const unsigned int numLanes = fromEdge->getNumLanes(); for (unsigned int i2 = 0; i2 < numLanes; i2++) { std::vector<NBEdge::Connection> approached = fromEdge->getConnectionsFromLane(i2); for (unsigned int i3 = 0; i3 < approached.size(); ++i3) { if (!fromEdge->mayBeTLSControlled(i2, approached[i3].toEdge, approached[i3].toLane)) { continue; } if (inChosen) { state[pos] = 'G'; } else { state[pos] = 'r'; } ++pos; } } } // correct behaviour for those that are not in chosen, but may drive, though for (unsigned int i1 = 0; i1 < pos; ++i1) { if (state[i1] == 'G') { continue; } bool isForbidden = false; for (unsigned int i2 = 0; i2 < pos && !isForbidden; ++i2) { if (state[i2] == 'G' && !isTurnaround[i2] && (forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1], true) || forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2], true))) { isForbidden = true; } } if (!isForbidden) { state[i1] = 'G'; } } // correct behaviour for those that have to wait (mainly left-mover) bool haveForbiddenLeftMover = false; for (unsigned int i1 = 0; i1 < pos; ++i1) { if (state[i1] != 'G') { continue; } for (unsigned int i2 = 0; i2 < pos; ++i2) { if ((state[i2] == 'G' || state[i2] == 'g') && forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1], true)) { state[i1] = 'g'; if (!isTurnaround[i1]) { haveForbiddenLeftMover = true; } } } } // add step logic->addStep(greenTime, state); if (brakingTime > 0) { // build yellow (straight) for (unsigned int i1 = 0; i1 < pos; ++i1) { if (state[i1] != 'G' && state[i1] != 'g') { continue; } if ((state[i1] >= 'a' && state[i1] <= 'z') && haveForbiddenLeftMover) { continue; } state[i1] = 'y'; } // add step logic->addStep(brakingTime, state); } if (haveForbiddenLeftMover && !myHaveSinglePhase) { // build left green for (unsigned int i1 = 0; i1 < pos; ++i1) { if (state[i1] == 'Y' || state[i1] == 'y') { state[i1] = 'r'; continue; } if (state[i1] == 'g') { state[i1] = 'G'; } } // add step logic->addStep(leftTurnTime, state); // build left yellow if (brakingTime > 0) { for (unsigned int i1 = 0; i1 < pos; ++i1) { if (state[i1] != 'G' && state[i1] != 'g') { continue; } state[i1] = 'y'; } // add step logic->addStep(brakingTime, state); } } } const SUMOTime totalDuration = logic->getDuration(); if (totalDuration > 0) { if (totalDuration > 3 * (greenTime + 2 * brakingTime + leftTurnTime)) { WRITE_WARNING("The traffic light '" + getID() + "' has a high cycle time of " + time2string(totalDuration) + "."); } return logic; } else { delete logic; return 0; } }
void NBEdgePriorityComputer::setPriorityJunctionPriorities(NBNode& n) { if (n.myIncomingEdges.size() == 0 || n.myOutgoingEdges.size() == 0) { return; } EdgeVector incoming = n.myIncomingEdges; EdgeVector outgoing = n.myOutgoingEdges; // what we do want to have is to extract the pair of roads that are // the major roads for this junction // let's get the list of incoming edges with the highest priority std::sort(incoming.begin(), incoming.end(), NBContHelper::edge_by_priority_sorter()); EdgeVector bestIncoming; NBEdge* best = incoming[0]; while (incoming.size() > 0 && samePriority(best, incoming[0])) { bestIncoming.push_back(*incoming.begin()); incoming.erase(incoming.begin()); } // now, let's get the list of best outgoing assert(outgoing.size() != 0); sort(outgoing.begin(), outgoing.end(), NBContHelper::edge_by_priority_sorter()); EdgeVector bestOutgoing; best = outgoing[0]; while (outgoing.size() > 0 && samePriority(best, outgoing[0])) { //->getPriority()==best->getPriority()) { bestOutgoing.push_back(*outgoing.begin()); outgoing.erase(outgoing.begin()); } // now, let's compute for each of the best incoming edges // the incoming which is most opposite // the outgoing which is most opposite EdgeVector::iterator i; std::map<NBEdge*, NBEdge*> counterIncomingEdges; std::map<NBEdge*, NBEdge*> counterOutgoingEdges; incoming = n.myIncomingEdges; outgoing = n.myOutgoingEdges; for (i = bestIncoming.begin(); i != bestIncoming.end(); ++i) { std::sort(incoming.begin(), incoming.end(), NBContHelper::edge_opposite_direction_sorter(*i, &n)); counterIncomingEdges[*i] = *incoming.begin(); std::sort(outgoing.begin(), outgoing.end(), NBContHelper::edge_opposite_direction_sorter(*i, &n)); counterOutgoingEdges[*i] = *outgoing.begin(); } // ok, let's try // 1) there is one best incoming road if (bestIncoming.size() == 1) { // let's mark this road as the best NBEdge* best1 = extractAndMarkFirst(n, bestIncoming); if (counterIncomingEdges.find(best1) != counterIncomingEdges.end()) { // ok, look, what we want is the opposit of the straight continuation edge // but, what if such an edge does not exist? By now, we'll determine it // geometrically NBEdge* s = counterIncomingEdges.find(best1)->second; if (GeomHelper::getMinAngleDiff(best1->getAngleAtNode(&n), s->getAngleAtNode(&n)) > 180 - 45) { s->setJunctionPriority(&n, 1); } } if (bestOutgoing.size() != 0) { // mark the best outgoing as the continuation sort(bestOutgoing.begin(), bestOutgoing.end(), NBContHelper::edge_similar_direction_sorter(best1)); best1 = extractAndMarkFirst(n, bestOutgoing); if (counterOutgoingEdges.find(best1) != counterOutgoingEdges.end()) { NBEdge* s = counterOutgoingEdges.find(best1)->second; if (GeomHelper::getMinAngleDiff(best1->getAngleAtNode(&n), s->getAngleAtNode(&n)) > 180 - 45) { s->setJunctionPriority(&n, 1); } } } return; } // ok, what we want to do in this case is to determine which incoming // has the best continuation... // This means, when several incoming roads have the same priority, // we want a (any) straight connection to be more priorised than a turning SUMOReal bestAngle = 0; NBEdge* bestFirst = 0; NBEdge* bestSecond = 0; bool hadBest = false; for (i = bestIncoming.begin(); i != bestIncoming.end(); ++i) { EdgeVector::iterator j; NBEdge* t1 = *i; SUMOReal angle1 = t1->getTotalAngle() + 180; if (angle1 >= 360) { angle1 -= 360; } for (j = i + 1; j != bestIncoming.end(); ++j) { NBEdge* t2 = *j; SUMOReal angle2 = t2->getTotalAngle() + 180; if (angle2 >= 360) { angle2 -= 360; } SUMOReal angle = GeomHelper::getMinAngleDiff(angle1, angle2); if (!hadBest || angle > bestAngle) { bestAngle = angle; bestFirst = *i; bestSecond = *j; hadBest = true; } } } bestFirst->setJunctionPriority(&n, 1); sort(bestOutgoing.begin(), bestOutgoing.end(), NBContHelper::edge_similar_direction_sorter(bestFirst)); if (bestOutgoing.size() != 0) { extractAndMarkFirst(n, bestOutgoing); } bestSecond->setJunctionPriority(&n, 1); sort(bestOutgoing.begin(), bestOutgoing.end(), NBContHelper::edge_similar_direction_sorter(bestSecond)); if (bestOutgoing.size() != 0) { extractAndMarkFirst(n, bestOutgoing); } }
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); } }
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."); } }