void NIImporter_OpenDrive::addViaConnectionSecure(const NBEdgeCont &ec, const NBNode * const node, const OpenDriveEdge &e, LinkType lt, const std::string &via, std::vector<NIImporter_OpenDrive::Connection> &connections) { NBEdge *from = 0; NBEdge *to = 0; if (node==e.to) { // the connection is at the end of the "positive" direction if (lt==OPENDRIVE_LT_PREDECESSOR) { // via -> edge to = ec.retrieve(e.id); } else { // -edge -> via // "ambigous?" from = ec.retrieve("-" + e.id); } } else { // the connection is at the begin of the "positive" direction if (lt==OPENDRIVE_LT_PREDECESSOR) { // via -> -edge to = ec.retrieve("-" + e.id); } else { // edge -> via // "ambigous?" from = ec.retrieve(e.id); } } if (from==0&&to==0) { throw ProcessError("Missing edge"); } Connection c(from, via, to); connections.push_back(c); }
void NWWriter_SUMO::writeRoundabout(OutputDevice& into, const std::vector<std::string>& edgeIDs, const NBEdgeCont& ec) { std::vector<std::string> validEdgeIDs; std::vector<std::string> invalidEdgeIDs; std::vector<std::string> nodeIDs; for (std::vector<std::string>::const_iterator i = edgeIDs.begin(); i != edgeIDs.end(); ++i) { const NBEdge* edge = ec.retrieve(*i); if (edge != 0) { nodeIDs.push_back(edge->getToNode()->getID()); validEdgeIDs.push_back(edge->getID()); } else { invalidEdgeIDs.push_back(*i); } } std::sort(nodeIDs.begin(), nodeIDs.end()); if (validEdgeIDs.size() > 0) { into.openTag(SUMO_TAG_ROUNDABOUT); into.writeAttr(SUMO_ATTR_NODES, joinToString(nodeIDs, " ")); into.writeAttr(SUMO_ATTR_EDGES, joinToString(validEdgeIDs, " ")); into.closeTag(); if (invalidEdgeIDs.size() > 0) { WRITE_WARNING("Writing incomplete roundabout. Edges: '" + joinToString(invalidEdgeIDs, " ") + "' no longer exist'"); } } }
void NBJoinedEdgesMap::init(NBEdgeCont& ec) { const std::vector<std::string> edgeNames = ec.getAllNames(); myMap.clear(); for (std::vector<std::string>::const_iterator i = edgeNames.begin(); i != edgeNames.end(); i++) { MappedEdgesVector e; e.push_back(*i); myMap[*i] = e; myLengths[*i] = ec.retrieve(*i)->getLength(); } }
void NBPTLine::write(OutputDevice& device, NBEdgeCont& ec) { device.openTag(SUMO_TAG_PT_LINE); device.writeAttr(SUMO_ATTR_ID, myPTLineId); if (!myName.empty()) { device.writeAttr(SUMO_ATTR_NAME, StringUtils::escapeXML(myName)); } device.writeAttr(SUMO_ATTR_LINE, StringUtils::escapeXML(myRef)); device.writeAttr(SUMO_ATTR_TYPE, myType); if (myInterval > 0) { // write seconds device.writeAttr(SUMO_ATTR_PERIOD, 60 * myInterval); } if (myNightService != "") { device.writeAttr("nightService", myNightService); } device.writeAttr("completeness", toString((double)myPTStops.size() / (double)myNumOfStops)); std::vector<std::string> validEdgeIDs; // filter out edges that have been removed due to joining junctions // (therest of the route is valid) for (NBEdge* e : myRoute) { if (ec.retrieve(e->getID())) { validEdgeIDs.push_back(e->getID()); } } if (!myRoute.empty()) { device.openTag(SUMO_TAG_ROUTE); device.writeAttr(SUMO_ATTR_EDGES, validEdgeIDs); device.closeTag(); } for (auto& myPTStop : myPTStops) { device.openTag(SUMO_TAG_BUS_STOP); device.writeAttr(SUMO_ATTR_ID, myPTStop->getID()); device.writeAttr(SUMO_ATTR_NAME, StringUtils::escapeXML(myPTStop->getName())); device.closeTag(); } // device.writeAttr(SUMO_ATTR_LANE, myLaneId); // device.writeAttr(SUMO_ATTR_STARTPOS, myStartPos); // device.writeAttr(SUMO_ATTR_ENDPOS, myEndPos); // device.writeAttr(SUMO_ATTR_FRIENDLY_POS, "true"); device.closeTag(); }
void NIImporter_OpenDrive::addE2EConnectionsSecure(const NBEdgeCont &ec, const NBNode * const node, const NIImporter_OpenDrive::OpenDriveEdge &from, const NIImporter_OpenDrive::OpenDriveEdge &to, std::vector<NIImporter_OpenDrive::Connection> &connections) { // positive direction (from is incoming, to is outgoing) NBEdge *fromEdge = ec.retrieve("-" + from.id); if (fromEdge==0||!node->hasIncoming(fromEdge)) { fromEdge = ec.retrieve(from.id); } NBEdge *toEdge = ec.retrieve("-" + to.id); if (toEdge==0||!node->hasOutgoing(toEdge)) { toEdge = ec.retrieve(to.id); } if (fromEdge!=0&&toEdge!=0) { Connection c(fromEdge, "", toEdge); setLaneConnections(c, from, c.from->getID()[0]!='-', c.from->getID()[0]=='-' ? SUMO_TAG_OPENDRIVE_RIGHT : SUMO_TAG_OPENDRIVE_LEFT, to, c.to->getID()[0]!='-', c.to->getID()[0]=='-' ? SUMO_TAG_OPENDRIVE_RIGHT : SUMO_TAG_OPENDRIVE_LEFT); connections.push_back(c); } // negative direction (to is incoming, from is outgoing) fromEdge = ec.retrieve("-" + from.id); if (fromEdge==0||!node->hasOutgoing(fromEdge)) { fromEdge = ec.retrieve(from.id); } toEdge = ec.retrieve("-" + to.id); if (toEdge==0||!node->hasIncoming(toEdge)) { toEdge = ec.retrieve(to.id); } if (fromEdge!=0&&toEdge!=0) { Connection c(toEdge, "", fromEdge); setLaneConnections(c, to, c.to->getID()[0]!='-', c.to->getID()[0]=='-' ? SUMO_TAG_OPENDRIVE_RIGHT : SUMO_TAG_OPENDRIVE_LEFT, from, c.from->getID()[0]!='-', c.from->getID()[0]=='-' ? SUMO_TAG_OPENDRIVE_RIGHT : SUMO_TAG_OPENDRIVE_LEFT); connections.push_back(c); } }
void NIVissimEdge::buildNBEdge(NBDistrictCont& dc, NBNodeCont& nc, NBEdgeCont& ec, SUMOReal sameNodesOffset) { // build the edge std::pair<NIVissimConnectionCluster*, NBNode*> fromInf, toInf; NBNode* fromNode, *toNode; fromNode = toNode = 0; sort(myConnectionClusters.begin(), myConnectionClusters.end(), connection_cluster_position_sorter(myID)); sort(myDistrictConnections.begin(), myDistrictConnections.end()); ConnectionClusters tmpClusters = myConnectionClusters; if (tmpClusters.size() != 0) { sort(tmpClusters.begin(), tmpClusters.end(), connection_cluster_position_sorter(myID)); // get or build the from-node // A node may have to be build when the edge starts or ends at // a parking place or something like this fromInf = getFromNode(nc, tmpClusters); fromNode = fromInf.second; // get or build the to-node //if(tmpClusters.size()>0) { toInf = getToNode(nc, tmpClusters); toNode = toInf.second; if (fromInf.first != 0 && toNode != 0 && fromInf.first->around(toNode->getPosition())) { WRITE_WARNING("Will not build edge '" + toString(myID) + "'."); myAmWithinJunction = true; return; } //} // if both nodes are the same, resolve the problem otherwise if (fromNode == toNode) { std::pair<NBNode*, NBNode*> tmp = resolveSameNode(nc, sameNodesOffset, fromNode, toNode); if (fromNode != tmp.first) { fromInf.first = 0; } if (toNode != tmp.second) { toInf.first = 0; } fromNode = tmp.first; toNode = tmp.second; } } // if (fromNode == 0) { fromInf.first = 0; Position pos = myGeom[0]; fromNode = new NBNode(toString<int>(myID) + "-SourceNode", pos, NODETYPE_NOJUNCTION); if (!nc.insert(fromNode)) { throw ProcessError("Could not insert node '" + fromNode->getID() + "' to nodes container."); } } if (toNode == 0) { toInf.first = 0; Position pos = myGeom[-1]; toNode = new NBNode(toString<int>(myID) + "-DestinationNode", pos, NODETYPE_NOJUNCTION); if (!nc.insert(toNode)) { throw ProcessError("Could not insert node '" + toNode->getID() + "' to nodes container."); } } // build the edge SUMOReal avgSpeed = 0; int i; for (i = 0; i < (int) myNoLanes; i++) { if (myLaneSpeeds.size() <= (size_t) i || myLaneSpeeds[i] == -1) { myLanesWithMissingSpeeds.push_back(toString(myID) + "_" + toString(i)); avgSpeed += OptionsCont::getOptions().getFloat("vissim.default-speed"); } else { avgSpeed += myLaneSpeeds[i]; } } avgSpeed /= (SUMOReal) myLaneSpeeds.size(); avgSpeed *= OptionsCont::getOptions().getFloat("vissim.speed-norm"); if (fromNode == toNode) { WRITE_WARNING("Could not build edge '" + toString(myID) + "'; would connect same node."); return; } NBEdge* buildEdge = new NBEdge(toString<int>(myID), fromNode, toNode, myType, avgSpeed / (SUMOReal) 3.6, myNoLanes, -1, NBEdge::UNSPECIFIED_WIDTH, NBEdge::UNSPECIFIED_OFFSET, myGeom, myName, LANESPREAD_CENTER, true); for (i = 0; i < (int) myNoLanes; i++) { if ((int) myLaneSpeeds.size() <= i || myLaneSpeeds[i] == -1) { buildEdge->setSpeed(i, OptionsCont::getOptions().getFloat("vissim.default-speed") / (SUMOReal) 3.6); } else { buildEdge->setSpeed(i, myLaneSpeeds[i] / (SUMOReal) 3.6); } } ec.insert(buildEdge); // check whether the edge contains any other clusters if (tmpClusters.size() > 0) { bool cont = true; for (ConnectionClusters::iterator j = tmpClusters.begin(); cont && j != tmpClusters.end(); ++j) { // split the edge at the previously build node std::string nextID = buildEdge->getID() + "[1]"; cont = ec.splitAt(dc, buildEdge, (*j)->getNBNode()); // !!! what to do if the edge could not be split? buildEdge = ec.retrieve(nextID); } } }
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; }
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); }
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); } } */ } }
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 NBRampsComputer::buildOnRamp(NBNode* cur, NBNodeCont& nc, NBEdgeCont& ec, NBDistrictCont& dc, SUMOReal rampLength, bool dontSplit, std::set<NBEdge*>& incremented) { NBEdge* potHighway, *potRamp, *cont; getOnRampEdges(cur, &potHighway, &potRamp, &cont); // compute the number of lanes to append const unsigned int firstLaneNumber = potHighway->getNumLanes(); int toAdd = (potRamp->getNumLanes() + firstLaneNumber) - cont->getNumLanes(); NBEdge* first = cont; NBEdge* last = cont; NBEdge* curr = cont; if (toAdd > 0 && find(incremented.begin(), incremented.end(), cont) == 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* nextN = curr->getToNode(); if (nextN->getOutgoingEdges().size() == 1) { curr = nextN->getOutgoingEdges()[0]; if (curr->getNumLanes() != firstLaneNumber) { // the number of lanes changes along the computation; we'll stop... 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; NBNode* rn = new NBNode(curr->getID() + "-AddedOnRampNode", curr->getGeometry().positionAtLengthPosition(rampLength - currLength)); 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() + ADDED_ON_RAMP_EDGE, curr->getID(), curr->getNumLanes() + toAdd, curr->getNumLanes()); if (!ok) { WRITE_ERROR("Ups - could not build on-ramp for edge '" + curr->getID() + "'!"); return; } //ec.retrieve(name)->invalidateConnections(); curr = ec.retrieve(name + ADDED_ON_RAMP_EDGE); curr->invalidateConnections(true); incremented.insert(curr); last = curr; moveRampRight(curr, toAdd); if (wasFirst) { first = curr; } } } // set connections from ramp/highway to added ramp if (!potHighway->addLane2LaneConnections(0, first, potRamp->getNumLanes(), MIN2(first->getNumLanes() - potRamp->getNumLanes(), potHighway->getNumLanes()), NBEdge::L2L_VALIDATED, true, true)) { throw ProcessError("Could not set connection!"); } if (!potRamp->addLane2LaneConnections(0, first, 0, potRamp->getNumLanes(), NBEdge::L2L_VALIDATED, true, true)) { throw ProcessError("Could not set connection!"); } // patch ramp geometry PositionVector p = potRamp->getGeometry(); p.pop_back(); p.push_back(first->getLaneShape(0)[0]); potRamp->setGeometry(p); // set connections from added ramp to following highway NBNode* nextN = last->getToNode(); if (nextN->getOutgoingEdges().size() == 1) { NBEdge* next = nextN->getOutgoingEdges()[0];//const EdgeVector& o1 = cont->getToNode()->getOutgoingEdges(); if (next->getNumLanes() < last->getNumLanes()) { last->addLane2LaneConnections(last->getNumLanes() - next->getNumLanes(), next, 0, next->getNumLanes(), NBEdge::L2L_VALIDATED); } } }