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)); }
void Plot::createCube(double length, const Triple& shift) { unsigned m = nodes.size(); nodes.push_back(Triple(0,0,0)+shift); nodes.push_back(Triple(0,0,length)+shift); nodes.push_back(Triple(0,length,length)+shift); nodes.push_back(Triple(0,length,0)+shift); nodes.push_back(Triple(length,0,0)+shift); nodes.push_back(Triple(length,0,length)+shift); nodes.push_back(Triple(length,length,length)+shift); nodes.push_back(Triple(length,length,0)+shift); edges.push_back(Edge(m+0, m+1)); edges.push_back(Edge(m+1, m+2)); edges.push_back(Edge(m+2, m+3)); edges.push_back(Edge(m+3, m+0)); unsigned n = 4; edges.push_back(Edge(m+0+n, m+1+n)); edges.push_back(Edge(m+1+n, m+2+n)); edges.push_back(Edge(m+2+n, m+3+n)); edges.push_back(Edge(m+3+n, m+0+n)); edges.push_back(Edge(m+0, m+0+n)); edges.push_back(Edge(m+1, m+1+n)); edges.push_back(Edge(m+2, m+2+n)); edges.push_back(Edge(m+3, m+3+n)); }
EdgeVector NBEdgeCont::getGeneratedFrom(const std::string& id) const { size_t len = id.length(); EdgeVector ret; for (EdgeCont::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) { std::string curr = (*i).first; // the next check makes it possibly faster - we don not have // to compare the names if (curr.length() <= len) { continue; } // the name must be the same as the given id but something // beginning with a '[' must be appended to it if (curr.substr(0, len) == id && curr[len] == '[') { ret.push_back((*i).second); continue; } // ok, maybe the edge is a compound made during joining of edges size_t pos = curr.find(id); // surely not if (pos == std::string::npos) { continue; } // check leading char if (pos > 0) { if (curr[pos - 1] != ']' && curr[pos - 1] != '+') { // actually, this is another id continue; } } if (pos + id.length() < curr.length()) { if (curr[pos + id.length()] != '[' && curr[pos + id.length()] != '+') { // actually, this is another id continue; } } ret.push_back((*i).second); } return ret; }
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; }
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)); } }
bool RootList::init(CompartmentSet& debuggees) { EdgeVector allRootEdges; EdgeVectorTracer tracer(rt, &allRootEdges, wantNames); ZoneSet debuggeeZones; if (!debuggeeZones.init()) return false; for (auto range = debuggees.all(); !range.empty(); range.popFront()) { if (!debuggeeZones.put(range.front()->zone())) return false; } js::TraceRuntime(&tracer); if (!tracer.okay) return false; TraceIncomingCCWs(&tracer, debuggees); if (!tracer.okay) return false; for (EdgeVector::Range r = allRootEdges.all(); !r.empty(); r.popFront()) { Edge& edge = r.front(); JSCompartment* compartment = edge.referent.compartment(); if (compartment && !debuggees.has(compartment)) continue; Zone* zone = edge.referent.zone(); if (zone && !debuggeeZones.has(zone)) continue; if (!edges.append(mozilla::Move(edge))) return false; } noGC.emplace(rt); return true; }
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; }
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; }
bool init(DeserializedNode& node) { if (!edges.reserve(node.edges.length())) return false; for (DeserializedEdge* edgep = node.edges.begin(); edgep != node.edges.end(); edgep++) { char16_t* name = nullptr; if (edgep->name) { name = NS_strdup(edgep->name); if (!name) return false; } auto referent = node.getEdgeReferent(*edgep); edges.infallibleAppend(mozilla::Move(Edge(name, referent))); } settle(); return true; }
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(); }
// check that for HEFace f the vertices TYPE are connected bool VoronoiDiagramChecker::faceVerticesConnected( HEFace f, VoronoiVertexStatus Vtype ) { VertexVector face_verts = vd->g.face_vertices(f); VertexVector type_verts; BOOST_FOREACH( HEVertex v, face_verts ) { if ( vd->g[v].status == Vtype ) type_verts.push_back(v); // build a vector of all Vtype vertices } assert( !type_verts.empty() ); if (type_verts.size()==1) // set of 1 is allways connected return true; // check that type_verts are connected HEEdge currentEdge = vd->g[f].edge; HEVertex endVertex = vd->g.source(currentEdge); // stop when target here EdgeVector startEdges; bool done = false; while (!done) { HEVertex src = vd->g.source( currentEdge ); HEVertex trg = vd->g.target( currentEdge ); if ( vd->g[src].status != Vtype ) { // seach ?? - Vtype if ( vd->g[trg].status == Vtype ) { // we have found ?? - Vtype startEdges.push_back( currentEdge ); } } currentEdge = vd->g[currentEdge].next; if ( trg == endVertex ) { done = true; } } assert( !startEdges.empty() ); if ( startEdges.size() != 1 ) // when the Vtype vertices are connected, there is exactly one startEdge return false; else return true; }
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) + "'"); } }
void Plot::createCubic2() { unsigned xs = 2; unsigned ys = xs; unsigned zs = xs; unsigned i,j,k; for (i=0; i!=xs; ++i) for (j=0; j!=ys; ++j) for (k=0; k!=zs; ++k) nodes.push_back(Triple(i,j,k)); for (i=0; i!=nodes.size()-1; ++i) { edges.push_back(Edge(i,i+1)); } createDataset(nodes, edges); }
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 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 onChild(const JS::GCCellPtr& thing) override { if (!okay) return; // Don't trace permanent atoms and well-known symbols that are owned by // a parent JSRuntime. if (thing.is<JSString>() && thing.as<JSString>().isPermanentAtom()) return; if (thing.is<JS::Symbol>() && thing.as<JS::Symbol>().isWellKnownSymbol()) return; char16_t* name16 = nullptr; if (wantNames) { // Ask the tracer to compute an edge name for us. char buffer[1024]; getTracingEdgeName(buffer, sizeof(buffer)); const char* name = buffer; // Convert the name to char16_t characters. name16 = js_pod_malloc<char16_t>(strlen(name) + 1); if (!name16) { okay = false; return; } size_t i; for (i = 0; name[i]; i++) name16[i] = name[i]; name16[i] = '\0'; } // The simplest code is correct! The temporary Edge takes // ownership of name; if the append succeeds, the vector element // then takes ownership; if the append fails, then the temporary // retains it, and its destructor will free it. if (!vec->append(mozilla::Move(Edge(name16, Node(thing))))) { okay = false; return; } }
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(); }
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; }
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 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); } } }
void NIImporter_SUMO::_loadNetwork(OptionsCont& oc) { // check whether the option is set (properly) if (!oc.isUsableFileList("sumo-net-file")) { return; } // parse file(s) std::vector<std::string> files = oc.getStringVector("sumo-net-file"); for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) { if (!FileHelpers::isReadable(*file)) { WRITE_ERROR("Could not open sumo-net-file '" + *file + "'."); return; } setFileName(*file); PROGRESS_BEGIN_MESSAGE("Parsing sumo-net from '" + *file + "'"); XMLSubSys::runParser(*this, *file, true); PROGRESS_DONE_MESSAGE(); } // build edges for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) { EdgeAttrs* ed = (*i).second; // skip internal edges if (ed->func == EDGEFUNC_INTERNAL || ed->func == EDGEFUNC_CROSSING || ed->func == EDGEFUNC_WALKINGAREA) { continue; } // get and check the nodes NBNode* from = myNodeCont.retrieve(ed->fromNode); NBNode* to = myNodeCont.retrieve(ed->toNode); if (from == 0) { WRITE_ERROR("Edge's '" + ed->id + "' from-node '" + ed->fromNode + "' is not known."); continue; } if (to == 0) { WRITE_ERROR("Edge's '" + ed->id + "' to-node '" + ed->toNode + "' is not known."); continue; } // edge shape PositionVector geom; if (ed->shape.size() > 0) { geom = ed->shape; } else { // either the edge has default shape consisting only of the two node // positions or we have a legacy network geom = reconstructEdgeShape(ed, from->getPosition(), to->getPosition()); } // build and insert the edge NBEdge* e = new NBEdge(ed->id, from, to, ed->type, ed->maxSpeed, (unsigned int) ed->lanes.size(), ed->priority, NBEdge::UNSPECIFIED_WIDTH, NBEdge::UNSPECIFIED_OFFSET, geom, ed->streetName, "", ed->lsf, true); // always use tryIgnoreNodePositions to keep original shape e->setLoadedLength(ed->length); if (!myNetBuilder.getEdgeCont().insert(e)) { WRITE_ERROR("Could not insert edge '" + ed->id + "'."); delete e; continue; } ed->builtEdge = myNetBuilder.getEdgeCont().retrieve(ed->id); } // assign further lane attributes (edges are built) for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) { EdgeAttrs* ed = (*i).second; NBEdge* nbe = ed->builtEdge; if (nbe == 0) { // inner edge or removed by explicit list, vclass, ... continue; } for (unsigned int fromLaneIndex = 0; fromLaneIndex < (unsigned int) ed->lanes.size(); ++fromLaneIndex) { LaneAttrs* lane = ed->lanes[fromLaneIndex]; // connections const std::vector<Connection>& connections = lane->connections; for (std::vector<Connection>::const_iterator c_it = connections.begin(); c_it != connections.end(); c_it++) { const Connection& c = *c_it; if (myEdges.count(c.toEdgeID) == 0) { WRITE_ERROR("Unknown edge '" + c.toEdgeID + "' given in connection."); continue; } NBEdge* toEdge = myEdges[c.toEdgeID]->builtEdge; if (toEdge == 0) { // removed by explicit list, vclass, ... continue; } if (nbe->hasConnectionTo(toEdge, c.toLaneIdx)) { WRITE_WARNING("Target lane '" + toEdge->getLaneID(c.toLaneIdx) + "' has multiple connections from '" + nbe->getID() + "'."); } nbe->addLane2LaneConnection( fromLaneIndex, toEdge, c.toLaneIdx, NBEdge::L2L_VALIDATED, true, c.mayDefinitelyPass, c.keepClear, c.contPos); // maybe we have a tls-controlled connection if (c.tlID != "" && myRailSignals.count(c.tlID) == 0) { const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(c.tlID); if (programs.size() > 0) { std::map<std::string, NBTrafficLightDefinition*>::const_iterator it; for (it = programs.begin(); it != programs.end(); it++) { NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second); if (tlDef) { tlDef->addConnection(nbe, toEdge, fromLaneIndex, c.toLaneIdx, c.tlLinkNo); } else { throw ProcessError("Corrupt traffic light definition '" + c.tlID + "' (program '" + it->first + "')"); } } } else { WRITE_ERROR("The traffic light '" + c.tlID + "' is not known."); } } } // allow/disallow XXX preferred nbe->setPermissions(parseVehicleClasses(lane->allow, lane->disallow), fromLaneIndex); // width, offset nbe->setLaneWidth(fromLaneIndex, lane->width); nbe->setEndOffset(fromLaneIndex, lane->endOffset); nbe->setSpeed(fromLaneIndex, lane->maxSpeed); } nbe->declareConnectionsAsLoaded(); if (!nbe->hasLaneSpecificWidth() && nbe->getLanes()[0].width != NBEdge::UNSPECIFIED_WIDTH) { nbe->setLaneWidth(-1, nbe->getLaneWidth(0)); } if (!nbe->hasLaneSpecificEndOffset() && nbe->getEndOffset(0) != NBEdge::UNSPECIFIED_OFFSET) { nbe->setEndOffset(-1, nbe->getEndOffset(0)); } } // insert loaded prohibitions for (std::vector<Prohibition>::const_iterator it = myProhibitions.begin(); it != myProhibitions.end(); it++) { NBEdge* prohibitedFrom = myEdges[it->prohibitedFrom]->builtEdge; NBEdge* prohibitedTo = myEdges[it->prohibitedTo]->builtEdge; NBEdge* prohibitorFrom = myEdges[it->prohibitorFrom]->builtEdge; NBEdge* prohibitorTo = myEdges[it->prohibitorTo]->builtEdge; if (prohibitedFrom == 0) { WRITE_WARNING("Edge '" + it->prohibitedFrom + "' in prohibition was not built"); } else if (prohibitedTo == 0) { WRITE_WARNING("Edge '" + it->prohibitedTo + "' in prohibition was not built"); } else if (prohibitorFrom == 0) { WRITE_WARNING("Edge '" + it->prohibitorFrom + "' in prohibition was not built"); } else if (prohibitorTo == 0) { WRITE_WARNING("Edge '" + it->prohibitorTo + "' in prohibition was not built"); } else { NBNode* n = prohibitedFrom->getToNode(); n->addSortedLinkFoes( NBConnection(prohibitorFrom, prohibitorTo), NBConnection(prohibitedFrom, prohibitedTo)); } } if (!myHaveSeenInternalEdge) { myNetBuilder.haveLoadedNetworkWithoutInternalEdges(); } if (oc.isDefault("lefthand")) { oc.set("lefthand", toString(myAmLefthand)); } if (oc.isDefault("junctions.corner-detail")) { oc.set("junctions.corner-detail", toString(myCornerDetail)); } if (oc.isDefault("junctions.internal-link-detail") && myLinkDetail > 0) { oc.set("junctions.internal-link-detail", toString(myLinkDetail)); } if (!deprecatedVehicleClassesSeen.empty()) { WRITE_WARNING("Deprecated vehicle class(es) '" + toString(deprecatedVehicleClassesSeen) + "' in input network."); deprecatedVehicleClassesSeen.clear(); } // add loaded crossings if (!oc.getBool("no-internal-links")) { for (std::map<std::string, std::vector<Crossing> >::const_iterator it = myPedestrianCrossings.begin(); it != myPedestrianCrossings.end(); ++it) { NBNode* node = myNodeCont.retrieve((*it).first); for (std::vector<Crossing>::const_iterator it_c = (*it).second.begin(); it_c != (*it).second.end(); ++it_c) { const Crossing& crossing = (*it_c); EdgeVector edges; for (std::vector<std::string>::const_iterator it_e = crossing.crossingEdges.begin(); it_e != crossing.crossingEdges.end(); ++it_e) { NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(*it_e); // edge might have been removed due to options if (edge != 0) { edges.push_back(edge); } } if (edges.size() > 0) { node->addCrossing(edges, crossing.width, crossing.priority, true); } } } } // add roundabouts for (std::vector<std::vector<std::string> >::const_iterator it = myRoundabouts.begin(); it != myRoundabouts.end(); ++it) { EdgeSet roundabout; for (std::vector<std::string>::const_iterator it_r = it->begin(); it_r != it->end(); ++it_r) { NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(*it_r); if (edge == 0) { if (!myNetBuilder.getEdgeCont().wasIgnored(*it_r)) { WRITE_ERROR("Unknown edge '" + (*it_r) + "' in roundabout"); } } else { roundabout.insert(edge); } } myNetBuilder.getEdgeCont().addRoundabout(roundabout); } }
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."); } }
void settle() { front_ = i < edges.length() ? &edges[i] : nullptr; }
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 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); } }