bool NIVissimTL::NIVissimTLSignal::addTo(NBEdgeCont& ec, NBLoadedTLDef* tl) const { NIVissimConnection* c = NIVissimConnection::dictionary(myEdgeID); NBConnectionVector assignedConnections; if (c == 0) { // What to do if on an edge? -> close all outgoing connections NBEdge* edge = ec.retrievePossiblySplit(toString<int>(myEdgeID), myPosition); if (edge == 0) { WRITE_WARNING("Could not set tls signal at edge '" + toString(myEdgeID) + "' - the edge was not built."); return false; } // Check whether it is already known, which edges are approached // by which lanes // check whether to use the original lanes only if (edge->lanesWereAssigned()) { std::vector<NBEdge::Connection> connections = edge->getConnectionsFromLane(myLane - 1); for (std::vector<NBEdge::Connection>::iterator i = connections.begin(); i != connections.end(); i++) { const NBEdge::Connection& conn = *i; assert(myLane - 1 < (int)edge->getNumLanes()); assignedConnections.push_back(NBConnection(edge, myLane - 1, conn.toEdge, conn.toLane)); } } else { WRITE_WARNING("Edge : Lanes were not assigned(!)"); for (unsigned int j = 0; j < edge->getNumLanes(); j++) { std::vector<NBEdge::Connection> connections = edge->getConnectionsFromLane(j); for (std::vector<NBEdge::Connection>::iterator i = connections.begin(); i != connections.end(); i++) { const NBEdge::Connection& conn = *i; assignedConnections.push_back(NBConnection(edge, j, conn.toEdge, conn.toLane)); } } } } else { // get the edges NBEdge* tmpFrom = ec.retrievePossiblySplit(toString<int>(c->getFromEdgeID()), toString<int>(c->getToEdgeID()), true); NBEdge* tmpTo = ec.retrievePossiblySplit(toString<int>(c->getToEdgeID()), toString<int>(c->getFromEdgeID()), false); // check whether the edges are known if (tmpFrom != 0 && tmpTo != 0) { // add connections this signal is responsible for assignedConnections.push_back(NBConnection(tmpFrom, -1, tmpTo, -1)); } else { return false; // !!! one of the edges could not be build } } // add to the group assert(myGroupIDs.size() != 0); // @todo just another hack?! /* if (myGroupIDs.size() == 1) { return tl->addToSignalGroup(toString<int>(*(myGroupIDs.begin())), assignedConnections); } else { // !!! return tl->addToSignalGroup(toString<int>(*(myGroupIDs.begin())), assignedConnections); } */ return tl->addToSignalGroup(toString<int>(myGroupIDs.front()), assignedConnections); }
bool NIImporter_DlrNavteq::ConnectedLanesHandler::report(const std::string& result) { if (result[0] == '#') { return true; } StringTokenizer st(result, StringTokenizer::TAB); if (st.size() == 1) { return true; // one line with the number of data containing lines in it (also starts with a comment # since ersion 6.5) } assert(st.size() >= 7); const std::string nodeID = st.next(); const std::string vehicleType = st.next(); const std::string fromLaneS = st.next(); const std::string toLaneS = st.next(); const std::string throughTraffic = st.next(); const std::string startEdge = st.next(); const std::string endEdge = st.get(st.size() - 1); NBEdge* from = myEdgeCont.retrieve(startEdge); if (from == nullptr) { WRITE_WARNING("Ignoring prohibition from unknown start edge '" + startEdge + "'"); return true; } NBEdge* to = myEdgeCont.retrieve(endEdge); if (to == nullptr) { WRITE_WARNING("Ignoring prohibition from unknown end edge '" + endEdge + "'"); return true; } int fromLane = StringUtils::toInt(fromLaneS) - 1; // one based if (fromLane < 0 || fromLane >= from->getNumLanes()) { WRITE_WARNING("Ignoring invalid lane index '" + fromLaneS + "' in connection from edge '" + startEdge + "' with " + toString(from->getNumLanes()) + " lanes"); return true; } int toLane = StringUtils::toInt(toLaneS) - 1; // one based if (toLane < 0 || toLane >= to->getNumLanes()) { WRITE_WARNING("Ignoring invalid lane index '" + toLaneS + "' in connection to edge '" + endEdge + "' with " + toString(to->getNumLanes()) + " lanes"); return true; } if (!from->addLane2LaneConnection(fromLane, to, toLane, NBEdge::L2L_USER, true)) { if (OptionsCont::getOptions().getBool("show-errors.connections-first-try")) { WRITE_WARNING("Could not set loaded connection from '" + from->getLaneID(fromLane) + "' to '" + to->getLaneID(toLane) + "'."); } // set as to be re-applied after network processing // if this connection runs across a node cluster it may not be possible to set this const bool warnOnly = st.size() > 7; myEdgeCont.addPostProcessConnection(from->getID(), fromLane, to->getID(), toLane, false, true, NBEdge::UNSPECIFIED_CONTPOS, NBEdge::UNSPECIFIED_VISIBILITY_DISTANCE, NBEdge::UNSPECIFIED_SPEED, PositionVector::EMPTY, false, warnOnly); } // ensure that connections for other lanes are guessed if not specified from->declareConnectionsAsLoaded(NBEdge::INIT); from->getLaneStruct(fromLane).connectionsDone = true; return true; }
void NBTrafficLightDefinition::collectAllLinks() { myControlledLinks.clear(); int tlIndex = 0; // build the list of links which are controled by the traffic light for (EdgeVector::iterator i = myIncomingEdges.begin(); i != myIncomingEdges.end(); i++) { NBEdge* incoming = *i; unsigned int noLanes = incoming->getNumLanes(); for (unsigned int j = 0; j < noLanes; j++) { std::vector<NBEdge::Connection> connected = incoming->getConnectionsFromLane(j); for (std::vector<NBEdge::Connection>::iterator k = connected.begin(); k != connected.end(); k++) { const NBEdge::Connection& el = *k; if (incoming->mayBeTLSControlled(el.fromLane, el.toEdge, el.toLane)) { if (el.toEdge != 0 && el.toLane >= (int) el.toEdge->getNumLanes()) { throw ProcessError("Connection '" + incoming->getID() + "_" + toString(j) + "->" + el.toEdge->getID() + "_" + toString(el.toLane) + "' yields in a not existing lane."); } if (incoming->getToNode()->getType() != NODETYPE_RAIL_CROSSING || !isRailway(incoming->getPermissions())) { myControlledLinks.push_back(NBConnection(incoming, el.fromLane, el.toEdge, el.toLane, tlIndex++)); } else { myControlledLinks.push_back(NBConnection(incoming, el.fromLane, el.toEdge, el.toLane, -1)); } } } } } }
void NWWriter_DlrNavteq::writeLinksUnsplitted(const OptionsCont& oc, NBEdgeCont& ec) { std::map<const std::string, std::string> nameIDs; OutputDevice& device = OutputDevice::getDevice(oc.getString("dlr-navteq-output") + "_links_unsplitted.txt"); writeHeader(device, oc); // write format specifier device << "# LINK_ID\tNODE_ID_FROM\tNODE_ID_TO\tBETWEEN_NODE_ID\tLENGTH\tVEHICLE_TYPE\tFORM_OF_WAY\tBRUNNEL_TYPE\tFUNCTIONAL_ROAD_CLASS\tSPEED_CATEGORY\tNUMBER_OF_LANES\tSPEED_LIMIT\tSPEED_RESTRICTION\tNAME_ID1_REGIONAL\tNAME_ID2_LOCAL\tHOUSENUMBERS_RIGHT\tHOUSENUMBERS_LEFT\tZIP_CODE\tAREA_ID\tSUBAREA_ID\tTHROUGH_TRAFFIC\tSPECIAL_RESTRICTIONS\tEXTENDED_NUMBER_OF_LANES\tISRAMP\tCONNECTION\n"; // write edges for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) { NBEdge* e = (*i).second; const int kph = speedInKph(e->getSpeed()); const std::string& betweenNodeID = (e->getGeometry().size() > 2) ? e->getID() : UNDEFINED; std::string nameID = UNDEFINED; if (oc.getBool("output.street-names")) { const std::string& name = i->second->getStreetName(); if (name != "" && nameIDs.count(name) == 0) { nameID = toString(nameIDs.size()); nameIDs[name] = nameID; } } device << e->getID() << "\t" << e->getFromNode()->getID() << "\t" << e->getToNode()->getID() << "\t" << betweenNodeID << "\t" << getGraphLength(e) << "\t" << getAllowedTypes(e->getPermissions()) << "\t" << "3\t" // Speed Category 1-8 XXX refine this << UNDEFINED << "\t" // no special brunnel type (we don't know yet) << getRoadClass(e) << "\t" << getSpeedCategory(kph) << "\t" << getNavteqLaneCode(e->getNumLanes()) << "\t" << getSpeedCategoryUpperBound(kph) << "\t" << kph << "\t" << nameID << "\t" // NAME_ID1_REGIONAL XXX << UNDEFINED << "\t" // NAME_ID2_LOCAL XXX << UNDEFINED << "\t" // housenumbers_right << UNDEFINED << "\t" // housenumbers_left << UNDEFINED << "\t" // ZIP_CODE << UNDEFINED << "\t" // AREA_ID << UNDEFINED << "\t" // SUBAREA_ID << "1\t" // through_traffic (allowed) << UNDEFINED << "\t" // special_restrictions << UNDEFINED << "\t" // extended_number_of_lanes << UNDEFINED << "\t" // isRamp << "0\t" // connection (between nodes always in order) << "\n"; } if (oc.getBool("output.street-names")) { OutputDevice& namesDevice = OutputDevice::getDevice(oc.getString("dlr-navteq-output") + "_names.txt"); writeHeader(namesDevice, oc); // write format specifier namesDevice << "# NAME_ID\tName\n" << nameIDs.size() << "\n"; for (std::map<const std::string, std::string>::const_iterator i = nameIDs.begin(); i != nameIDs.end(); ++i) { namesDevice << i->second << "\t" << i->first << "\n"; } } }
unsigned int NIVissimConnection::buildEdgeConnections(NBEdgeCont& ec) { unsigned int unsetConnections = 0; // try to determine the connected edges NBEdge* fromEdge = 0; NBEdge* toEdge = 0; NIVissimEdge* vissimFrom = NIVissimEdge::dictionary(getFromEdgeID()); if (vissimFrom->wasWithinAJunction()) { // this edge was not built, try to get one that approaches it vissimFrom = vissimFrom->getBestIncoming(); if (vissimFrom != 0) { fromEdge = ec.retrievePossiblySplit(toString(vissimFrom->getID()), toString(getFromEdgeID()), true); } } else { // this edge was built, try to get the proper part fromEdge = ec.retrievePossiblySplit(toString(getFromEdgeID()), toString(getToEdgeID()), true); } NIVissimEdge* vissimTo = NIVissimEdge::dictionary(getToEdgeID()); if (vissimTo->wasWithinAJunction()) { vissimTo = vissimTo->getBestOutgoing(); if (vissimTo != 0) { toEdge = ec.retrievePossiblySplit(toString(vissimTo->getID()), toString(getToEdgeID()), true); } } else { toEdge = ec.retrievePossiblySplit(toString(getToEdgeID()), toString(getFromEdgeID()), false); } // try to get the edges the current connection connects /* NBEdge *fromEdge = ec.retrievePossiblySplit(toString(getFromEdgeID()), toString(getToEdgeID()), true); NBEdge *toEdge = ec.retrievePossiblySplit(toString(getToEdgeID()), toString(getFromEdgeID()), false); */ if (fromEdge == 0 || toEdge == 0) { WRITE_WARNING("Could not build connection between '" + toString(getFromEdgeID()) + "' and '" + toString(getToEdgeID()) + "'."); return 1; // !!! actually not 1 } recheckLanes(fromEdge, toEdge); const std::vector<int>& fromLanes = getFromLanes(); const std::vector<int>& toLanes = getToLanes(); if (fromLanes.size() != toLanes.size()) { WRITE_WARNING("Lane sizes differ for connection '" + toString(getID()) + "'."); } else { for (unsigned int index = 0; index < fromLanes.size(); ++index) { if (fromEdge->getNumLanes() <= static_cast<unsigned int>(fromLanes[index])) { WRITE_WARNING("Could not set connection between '" + fromEdge->getID() + "_" + toString(fromLanes[index]) + "' and '" + toEdge->getID() + "_" + toString(toLanes[index]) + "'."); ++unsetConnections; } else if (!fromEdge->addLane2LaneConnection(fromLanes[index], toEdge, toLanes[index], NBEdge::L2L_VALIDATED)) { WRITE_WARNING("Could not set connection between '" + fromEdge->getID() + "_" + toString(fromLanes[index]) + "' and '" + toEdge->getID() + "_" + toString(toLanes[index]) + "'."); ++unsetConnections; } } } return unsetConnections; }
void NBLoadedTLDef::collectLinks() { myControlledLinks.clear(); // build the list of links which are controled by the traffic light for (EdgeVector::iterator i = myIncomingEdges.begin(); i != myIncomingEdges.end(); i++) { NBEdge* incoming = *i; unsigned int noLanes = incoming->getNumLanes(); for (unsigned int j = 0; j < noLanes; j++) { std::vector<NBEdge::Connection> elv = incoming->getConnectionsFromLane(j); for (std::vector<NBEdge::Connection>::iterator k = elv.begin(); k != elv.end(); k++) { NBEdge::Connection el = *k; if (el.toEdge != 0) { myControlledLinks.push_back(NBConnection(incoming, j, el.toEdge, el.toLane)); } } } } // assign tl-indices to myControlledLinks unsigned int pos = 0; for (SignalGroupCont::const_iterator m = mySignalGroups.begin(); m != mySignalGroups.end(); m++) { SignalGroup* group = (*m).second; unsigned int linkNo = group->getLinkNo(); for (unsigned int j = 0; j < linkNo; j++) { const NBConnection& conn = group->getConnection(j); assert(conn.getFromLane() < 0 || (int) conn.getFrom()->getNumLanes() > conn.getFromLane()); NBConnection tst(conn); tst.setTLIndex(pos); if (tst.check(*myEdgeCont)) { if (tst.getFrom()->mayBeTLSControlled(tst.getFromLane(), tst.getTo(), tst.getToLane())) { for (NBConnectionVector::iterator it = myControlledLinks.begin(); it != myControlledLinks.end(); it++) { NBConnection& c = *it; if (c.getTLIndex() == NBConnection::InvalidTlIndex && tst.getFrom() == c.getFrom() && tst.getTo() == c.getTo() && (tst.getFromLane() < 0 || tst.getFromLane() == c.getFromLane()) && (tst.getToLane() < 0 || tst.getToLane() == c.getToLane())) { c.setTLIndex(pos); } } //std::cout << getID() << " group=" << (*m).first << " tst=" << tst << "\n"; pos++; } } else { WRITE_WARNING("Could not set signal on connection (signal: " + getID() + ", group: " + group->getID() + ")"); } } } }
void NBLoadedTLDef::collectLinks() { myControlledLinks.clear(); // build the list of links which are controled by the traffic light for (EdgeVector::iterator i = myIncomingEdges.begin(); i != myIncomingEdges.end(); i++) { NBEdge* incoming = *i; unsigned int noLanes = incoming->getNumLanes(); for (unsigned int j = 0; j < noLanes; j++) { std::vector<NBEdge::Connection> elv = incoming->getConnectionsFromLane(j); for (std::vector<NBEdge::Connection>::iterator k = elv.begin(); k != elv.end(); k++) { NBEdge::Connection el = *k; if (el.toEdge != 0) { myControlledLinks.push_back(NBConnection(incoming, j, el.toEdge, el.toLane)); } } } } }
void NIXMLEdgesHandler::myEndElement(int element) { if (element == SUMO_TAG_EDGE && myCurrentEdge != 0) { if (!myIsUpdate) { try { if (!myEdgeCont.insert(myCurrentEdge)) { WRITE_ERROR("Duplicate edge occured. ID='" + myCurrentID + "'"); delete myCurrentEdge; } } catch (InvalidArgument& e) { WRITE_ERROR(e.what()); throw; } catch (...) { WRITE_ERROR("An important information is missing in edge '" + myCurrentID + "'."); } } if (mySplits.size() != 0) { std::vector<Split>::iterator i; NBEdge* e = myCurrentEdge; sort(mySplits.begin(), mySplits.end(), split_sorter()); unsigned int noLanesMax = e->getNumLanes(); // compute the node positions and sort the lanes for (i = mySplits.begin(); i != mySplits.end(); ++i) { (*i).gpos = e->getGeometry().positionAtLengthPosition((*i).pos); sort((*i).lanes.begin(), (*i).lanes.end()); noLanesMax = MAX2(noLanesMax, (unsigned int)(*i).lanes.size()); } // split the edge std::vector<int> currLanes; for (unsigned int l = 0; l < e->getNumLanes(); ++l) { currLanes.push_back(l); } std::string edgeid = e->getID(); SUMOReal seen = 0; for (i = mySplits.begin(); i != mySplits.end(); ++i) { const Split& exp = *i; assert(exp.lanes.size() != 0); if (exp.pos > 0 && e->getGeometry().length() + seen > exp.pos && exp.pos > seen) { std::string nid = edgeid + "." + toString(exp.nameid); NBNode* rn = new NBNode(nid, exp.gpos); if (myNodeCont.insert(rn)) { // split the edge std::string nid = myCurrentID + "." + toString(exp.nameid); std::string pid = e->getID(); myEdgeCont.splitAt(myDistrictCont, e, exp.pos - seen, rn, pid, nid, e->getNumLanes(), (unsigned int) exp.lanes.size()); seen = exp.pos; std::vector<int> newLanes = exp.lanes; NBEdge* pe = myEdgeCont.retrieve(pid); NBEdge* ne = myEdgeCont.retrieve(nid); // reconnect lanes pe->invalidateConnections(true); // new on right unsigned int rightMostP = currLanes[0]; unsigned int rightMostN = newLanes[0]; for (int l = 0; l < (int) rightMostP - (int) rightMostN; ++l) { pe->addLane2LaneConnection(0, ne, l, NBEdge::L2L_VALIDATED, true); } // new on left unsigned int leftMostP = currLanes.back(); unsigned int leftMostN = newLanes.back(); for (int l = 0; l < (int) leftMostN - (int) leftMostP; ++l) { pe->addLane2LaneConnection(pe->getNumLanes() - 1, ne, leftMostN - l - rightMostN, NBEdge::L2L_VALIDATED, true); } // all other connected for (unsigned int l = 0; l < noLanesMax; ++l) { if (find(currLanes.begin(), currLanes.end(), l) == currLanes.end()) { continue; } if (find(newLanes.begin(), newLanes.end(), l) == newLanes.end()) { continue; } pe->addLane2LaneConnection(l - rightMostP, ne, l - rightMostN, NBEdge::L2L_VALIDATED, true); } // move to next e = ne; currLanes = newLanes; } else { WRITE_WARNING("Error on parsing a split (edge '" + myCurrentID + "')."); } } else if (exp.pos == 0) { if (e->getNumLanes() < exp.lanes.size()) { e->incLaneNo((int) exp.lanes.size() - e->getNumLanes()); } else { e->decLaneNo(e->getNumLanes() - (int) exp.lanes.size()); } currLanes = exp.lanes; } else { WRITE_WARNING("Split at '" + toString(exp.pos) + "' lies beyond the edge's length (edge '" + myCurrentID + "')."); } } // patch lane offsets e = myEdgeCont.retrieve(edgeid); i = mySplits.begin(); if ((*i).pos != 0) { e = e->getToNode()->getOutgoingEdges()[0]; } for (; i != mySplits.end(); ++i) { unsigned int maxLeft = (*i).lanes.back(); SUMOReal offset = 0; if (maxLeft < noLanesMax) { if (e->getLaneSpreadFunction() == LANESPREAD_RIGHT) { offset = SUMO_const_laneWidthAndOffset * (noLanesMax - 1 - maxLeft); } else { offset = SUMO_const_halfLaneAndOffset * (noLanesMax - 1 - maxLeft); } } unsigned int maxRight = (*i).lanes.front(); if (maxRight > 0 && e->getLaneSpreadFunction() == LANESPREAD_CENTER) { offset -= SUMO_const_halfLaneAndOffset * maxRight; } if (offset != 0) { PositionVector g = e->getGeometry(); g.move2side(offset); e->setGeometry(g); } if (e->getToNode()->getOutgoingEdges().size() != 0) { e = e->getToNode()->getOutgoingEdges()[0]; } } } } }
bool NBEdgeCont::splitAt(NBDistrictCont& dc, NBEdge* edge, SUMOReal pos, NBNode* node, const std::string& firstEdgeName, const std::string& secondEdgeName, unsigned int noLanesFirstEdge, unsigned int noLanesSecondEdge) { // build the new edges' geometries std::pair<PositionVector, PositionVector> geoms = edge->getGeometry().splitAt(pos); if (geoms.first[-1] != node->getPosition()) { geoms.first.pop_back(); geoms.first.push_back(node->getPosition()); } if (geoms.second[0] != node->getPosition()) { geoms.second.pop_front(); geoms.second.push_front(node->getPosition()); } // build and insert the edges NBEdge* one = new NBEdge(firstEdgeName, edge->myFrom, node, edge->myType, edge->mySpeed, noLanesFirstEdge, edge->getPriority(), edge->myLaneWidth, 0, geoms.first, edge->getStreetName(), edge->myLaneSpreadFunction, true); for (unsigned int i = 0; i < noLanesFirstEdge && i < edge->getNumLanes(); i++) { one->setSpeed(i, edge->getLaneSpeed(i)); } NBEdge* two = new NBEdge(secondEdgeName, node, edge->myTo, edge->myType, edge->mySpeed, noLanesSecondEdge, edge->getPriority(), edge->myLaneWidth, edge->myOffset, geoms.second, edge->getStreetName(), edge->myLaneSpreadFunction, true); for (unsigned int i = 0; i < noLanesSecondEdge && i < edge->getNumLanes(); i++) { two->setSpeed(i, edge->getLaneSpeed(i)); } two->copyConnectionsFrom(edge); // replace information about this edge within the nodes edge->myFrom->replaceOutgoing(edge, one, 0); edge->myTo->replaceIncoming(edge, two, 0); // the edge is now occuring twice in both nodes... // clean up edge->myFrom->removeDoubleEdges(); edge->myTo->removeDoubleEdges(); // add connections from the first to the second edge // check special case: // one in, one out, the outgoing has one lane more if (noLanesFirstEdge == noLanesSecondEdge - 1) { for (unsigned int i = 0; i < one->getNumLanes(); i++) { if (!one->addLane2LaneConnection(i, two, i + 1, NBEdge::L2L_COMPUTED)) { // !!! Bresenham, here!!! throw ProcessError("Could not set connection!"); } } one->addLane2LaneConnection(0, two, 0, NBEdge::L2L_COMPUTED); } else { for (unsigned int i = 0; i < one->getNumLanes() && i < two->getNumLanes(); i++) { if (!one->addLane2LaneConnection(i, two, i, NBEdge::L2L_COMPUTED)) {// !!! Bresenham, here!!! throw ProcessError("Could not set connection!"); } } } if (myRemoveEdgesAfterJoining) { if (find(myEdges2Keep.begin(), myEdges2Keep.end(), edge->getID()) != myEdges2Keep.end()) { myEdges2Keep.insert(one->getID()); myEdges2Keep.insert(two->getID()); } if (find(myEdges2Remove.begin(), myEdges2Remove.end(), edge->getID()) != myEdges2Remove.end()) { myEdges2Remove.insert(one->getID()); myEdges2Remove.insert(two->getID()); } } // erase the splitted edge erase(dc, edge); insert(one, true); insert(two, true); myEdgesSplit++; 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 NIXMLEdgesHandler::myEndElement(int element) { if (element == SUMO_TAG_EDGE && myCurrentEdge != 0) { // add bike lane, wait until lanes are loaded to avoid building if it already exists if (myBikeLaneWidth != NBEdge::UNSPECIFIED_WIDTH) { myCurrentEdge->addBikeLane(myBikeLaneWidth); } // add sidewalk, wait until lanes are loaded to avoid building if it already exists if (mySidewalkWidth != NBEdge::UNSPECIFIED_WIDTH) { myCurrentEdge->addSidewalk(mySidewalkWidth); } if (!myIsUpdate) { try { if (!myEdgeCont.insert(myCurrentEdge)) { WRITE_ERROR("Duplicate edge occured. ID='" + myCurrentID + "'"); delete myCurrentEdge; } } catch (InvalidArgument& e) { WRITE_ERROR(e.what()); throw; } catch (...) { WRITE_ERROR("An important information is missing in edge '" + myCurrentID + "'."); } } if (mySplits.size() != 0) { std::vector<Split>::iterator i; NBEdge* e = myCurrentEdge; sort(mySplits.begin(), mySplits.end(), split_sorter()); unsigned int noLanesMax = e->getNumLanes(); // compute the node positions and sort the lanes for (i = mySplits.begin(); i != mySplits.end(); ++i) { sort((*i).lanes.begin(), (*i).lanes.end()); noLanesMax = MAX2(noLanesMax, (unsigned int)(*i).lanes.size()); } // split the edge std::vector<int> currLanes; for (unsigned int l = 0; l < e->getNumLanes(); ++l) { currLanes.push_back(l); } if (e->getNumLanes() != mySplits.back().lanes.size()) { // invalidate traffic light definitions loaded from a SUMO network // XXX it would be preferable to reconstruct the phase definitions heuristically e->getToNode()->invalidateTLS(myTLLogicCont); // if the number of lanes changes the connections should be // recomputed e->invalidateConnections(true); } std::string edgeid = e->getID(); SUMOReal seen = 0; for (i = mySplits.begin(); i != mySplits.end(); ++i) { const Split& exp = *i; assert(exp.lanes.size() != 0); if (exp.pos > 0 && e->getGeometry().length() + seen > exp.pos && exp.pos > seen) { if (myNodeCont.insert(exp.node)) { myNodeCont.markAsSplit(exp.node); // split the edge std::string pid = e->getID(); myEdgeCont.splitAt(myDistrictCont, e, exp.pos - seen, exp.node, pid, exp.node->getID(), e->getNumLanes(), (unsigned int) exp.lanes.size(), exp.speed); seen = exp.pos; std::vector<int> newLanes = exp.lanes; NBEdge* pe = myEdgeCont.retrieve(pid); NBEdge* ne = myEdgeCont.retrieve(exp.node->getID()); // reconnect lanes pe->invalidateConnections(true); // new on right unsigned int rightMostP = currLanes[0]; unsigned int rightMostN = newLanes[0]; for (int l = 0; l < (int) rightMostP - (int) rightMostN; ++l) { pe->addLane2LaneConnection(0, ne, l, NBEdge::L2L_VALIDATED, true); } // new on left unsigned int leftMostP = currLanes.back(); unsigned int leftMostN = newLanes.back(); for (int l = 0; l < (int) leftMostN - (int) leftMostP; ++l) { pe->addLane2LaneConnection(pe->getNumLanes() - 1, ne, leftMostN - l - rightMostN, NBEdge::L2L_VALIDATED, true); } // all other connected for (unsigned int l = 0; l < noLanesMax; ++l) { if (find(currLanes.begin(), currLanes.end(), l) == currLanes.end()) { continue; } if (find(newLanes.begin(), newLanes.end(), l) == newLanes.end()) { continue; } pe->addLane2LaneConnection(l - rightMostP, ne, l - rightMostN, NBEdge::L2L_VALIDATED, true); } // move to next e = ne; currLanes = newLanes; } else { WRITE_WARNING("Error on parsing a split (edge '" + myCurrentID + "')."); } } else if (exp.pos == 0) { if (e->getNumLanes() < exp.lanes.size()) { e->incLaneNo((int) exp.lanes.size() - e->getNumLanes()); } else { e->decLaneNo(e->getNumLanes() - (int) exp.lanes.size()); } currLanes = exp.lanes; // invalidate traffic light definition loaded from a SUMO network // XXX it would be preferable to reconstruct the phase definitions heuristically e->getFromNode()->invalidateTLS(myTLLogicCont); } else { WRITE_WARNING("Split at '" + toString(exp.pos) + "' lies beyond the edge's length (edge '" + myCurrentID + "')."); } } // patch lane offsets e = myEdgeCont.retrieve(edgeid); if (mySplits.front().pos != 0) { // add a dummy split at the beginning to ensure correct offset Split start; start.pos = 0; for (int lane = 0; lane < (int)e->getNumLanes(); ++lane) { start.lanes.push_back(lane); } mySplits.insert(mySplits.begin(), start); } i = mySplits.begin(); for (; i != mySplits.end(); ++i) { unsigned int maxLeft = (*i).lanes.back(); SUMOReal offset = 0; if (maxLeft < noLanesMax) { if (e->getLaneSpreadFunction() == LANESPREAD_RIGHT) { offset = SUMO_const_laneWidthAndOffset * (noLanesMax - 1 - maxLeft); } else { offset = SUMO_const_halfLaneAndOffset * (noLanesMax - 1 - maxLeft); } } unsigned int maxRight = (*i).lanes.front(); if (maxRight > 0 && e->getLaneSpreadFunction() == LANESPREAD_CENTER) { offset -= SUMO_const_halfLaneAndOffset * maxRight; } if (offset != 0) { PositionVector g = e->getGeometry(); g.move2side(offset); e->setGeometry(g); } if (e->getToNode()->getOutgoingEdges().size() != 0) { e = e->getToNode()->getOutgoingEdges()[0]; } } } } }
void NIImporter_VISUM::parse_LanesConnections() { // get the node NBNode* node = getNamedNode("KNOTNR", "KNOT"); if (node == 0) { return; } // get the from-edge NBEdge* fromEdge = getNamedEdgeContinuating("VONSTRNR", "VONSTR", node); NBEdge* toEdge = getNamedEdgeContinuating("NACHSTRNR", "NACHSTR", node); if (fromEdge == 0 || toEdge == 0) { return; } int fromLaneOffset = 0; if (!node->hasIncoming(fromEdge)) { fromLaneOffset = fromEdge->getNumLanes(); fromEdge = getReversedContinuating(fromEdge, node); } else { fromEdge = getReversedContinuating(fromEdge, node); NBEdge* tmp = myNetBuilder.getEdgeCont().retrieve(fromEdge->getID().substr(0, fromEdge->getID().find('_'))); fromLaneOffset = tmp->getNumLanes(); } int toLaneOffset = 0; if (!node->hasOutgoing(toEdge)) { toLaneOffset = toEdge->getNumLanes(); toEdge = getReversedContinuating(toEdge, node); } else { NBEdge* tmp = myNetBuilder.getEdgeCont().retrieve(toEdge->getID().substr(0, toEdge->getID().find('_'))); toLaneOffset = tmp->getNumLanes(); } // get the from-lane std::string fromLaneS = NBHelpers::normalIDRepresentation(myLineParser.get("VONFSNR")); int fromLane = -1; try { fromLane = TplConvert::_2int(fromLaneS.c_str()); } catch (NumberFormatException&) { WRITE_ERROR("A from-lane number for edge '" + fromEdge->getID() + "' is not numeric (" + fromLaneS + ")."); return; } fromLane -= 1; if (fromLane < 0) { WRITE_ERROR("A from-lane number for edge '" + fromEdge->getID() + "' is not positive (" + fromLaneS + ")."); return; } // get the from-lane std::string toLaneS = NBHelpers::normalIDRepresentation(myLineParser.get("NACHFSNR")); int toLane = -1; try { toLane = TplConvert::_2int(toLaneS.c_str()); } catch (NumberFormatException&) { WRITE_ERROR("A to-lane number for edge '" + toEdge->getID() + "' is not numeric (" + toLaneS + ")."); return; } toLane -= 1; if (toLane < 0) { WRITE_ERROR("A to-lane number for edge '" + toEdge->getID() + "' is not positive (" + toLaneS + ")."); return; } // !!! the next is probably a hack if (fromLane - fromLaneOffset < 0) { fromLaneOffset = 0; } else { fromLane = fromEdge->getNumLanes() - (fromLane - fromLaneOffset) - 1; } if (toLane - toLaneOffset < 0) { toLaneOffset = 0; } else { toLane = toEdge->getNumLanes() - (toLane - toLaneOffset) - 1; } // if ((int) fromEdge->getNumLanes() <= fromLane) { WRITE_ERROR("A from-lane number for edge '" + fromEdge->getID() + "' is larger than the edge's lane number (" + fromLaneS + ")."); return; } if ((int) toEdge->getNumLanes() <= toLane) { WRITE_ERROR("A to-lane number for edge '" + toEdge->getID() + "' is larger than the edge's lane number (" + toLaneS + ")."); return; } // fromEdge->addLane2LaneConnection(fromLane, toEdge, toLane, NBEdge::L2L_VALIDATED); }
void NIImporter_VISUM::parse_Lanes() { // get the node NBNode* node = getNamedNode("KNOTNR"); // get the edge NBEdge* baseEdge = getNamedEdge("STRNR"); NBEdge* edge = getNamedEdgeContinuating("STRNR", node); // check if (node == 0 || edge == 0) { return; } // get the lane std::string laneS = myLineParser.know("FSNR") ? NBHelpers::normalIDRepresentation(myLineParser.get("FSNR")) : NBHelpers::normalIDRepresentation(myLineParser.get("NR")); int lane = -1; try { lane = TplConvert::_2int(laneS.c_str()); } catch (NumberFormatException&) { WRITE_ERROR("A lane number for edge '" + edge->getID() + "' is not numeric (" + laneS + ")."); return; } lane -= 1; if (lane < 0) { WRITE_ERROR("A lane number for edge '" + edge->getID() + "' is not positive (" + laneS + ")."); return; } // get the direction std::string dirS = NBHelpers::normalIDRepresentation(myLineParser.get("RICHTTYP")); int prevLaneNo = baseEdge->getNumLanes(); if ((dirS == "1" && !(node->hasIncoming(edge))) || (dirS == "0" && !(node->hasOutgoing(edge)))) { // get the last part of the turnaround direction edge = getReversedContinuating(edge, node); } // get the length std::string lengthS = NBHelpers::normalIDRepresentation(myLineParser.get("LAENGE")); SUMOReal length = -1; try { length = TplConvert::_2SUMOReal(lengthS.c_str()); } catch (NumberFormatException&) { WRITE_ERROR("A lane length for edge '" + edge->getID() + "' is not numeric (" + lengthS + ")."); return; } if (length < 0) { WRITE_ERROR("A lane length for edge '" + edge->getID() + "' is not positive (" + lengthS + ")."); return; } // if (dirS == "1") { lane -= prevLaneNo; } // if (length == 0) { if ((int) edge->getNumLanes() > lane) { // ok, we know this already... return; } // increment by one edge->incLaneNo(1); } else { // check whether this edge already has been created if (edge->getID().substr(edge->getID().length() - node->getID().length() - 1) == "_" + node->getID()) { if (edge->getID().substr(edge->getID().find('_')) == "_" + toString(length) + "_" + node->getID()) { if ((int) edge->getNumLanes() > lane) { // ok, we know this already... return; } // increment by one edge->incLaneNo(1); return; } } // nope, we have to split the edge... // maybe it is not the proper edge to split - VISUM seems not to sort the splits... bool mustRecheck = true; SUMOReal seenLength = 0; while (mustRecheck) { if (edge->getID().substr(edge->getID().length() - node->getID().length() - 1) == "_" + node->getID()) { // ok, we have a previously created edge here std::string sub = edge->getID(); sub = sub.substr(sub.rfind('_', sub.rfind('_') - 1)); sub = sub.substr(1, sub.find('_', 1) - 1); SUMOReal dist = TplConvert::_2SUMOReal(sub.c_str()); if (dist < length) { seenLength += edge->getLength(); if (dirS == "1") { // incoming -> move back edge = edge->getFromNode()->getIncomingEdges()[0]; } else { // outgoing -> move forward edge = edge->getToNode()->getOutgoingEdges()[0]; } } else { mustRecheck = false; } } else { // we have the center edge - do not continue... mustRecheck = false; } } // compute position Position p; SUMOReal useLength = length - seenLength; useLength = edge->getLength() - useLength; std::string edgeID = edge->getID(); p = edge->getGeometry().positionAtLengthPosition(useLength); if (edgeID.substr(edgeID.length() - node->getID().length() - 1) == "_" + node->getID()) { edgeID = edgeID.substr(0, edgeID.find('_')); } NBNode* rn = new NBNode(edgeID + "_" + toString((size_t) length) + "_" + node->getID(), p); if (!myNetBuilder.getNodeCont().insert(rn)) { throw ProcessError("Ups - could not insert node!"); } std::string nid = edgeID + "_" + toString((size_t) length) + "_" + node->getID(); myNetBuilder.getEdgeCont().splitAt(myNetBuilder.getDistrictCont(), edge, useLength, rn, edge->getID(), nid, edge->getNumLanes() + 0, edge->getNumLanes() + 1); NBEdge* nedge = myNetBuilder.getEdgeCont().retrieve(nid); nedge = nedge->getToNode()->getOutgoingEdges()[0]; while (nedge->getID().substr(nedge->getID().length() - node->getID().length() - 1) == "_" + node->getID()) { assert(nedge->getToNode()->getOutgoingEdges().size() > 0); nedge->incLaneNo(1); nedge = nedge->getToNode()->getOutgoingEdges()[0]; } } }
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); } } }
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 NWWriter_XML::writeEdgesAndConnections(const OptionsCont& oc, NBNodeCont& nc, NBEdgeCont& ec) { const GeoConvHelper& gch = GeoConvHelper::getFinal(); bool useGeo = oc.exists("proj.plain-geo") && oc.getBool("proj.plain-geo"); const bool geoAccuracy = useGeo || gch.usingInverseGeoProjection(); OutputDevice& edevice = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".edg.xml"); edevice.writeXMLHeader("edges", NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/edges_file.xsd\""); OutputDevice& cdevice = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".con.xml"); cdevice.writeXMLHeader("connections", NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/connections_file.xsd\""); bool noNames = !oc.getBool("output.street-names"); for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) { // write the edge itself to the edges-files NBEdge* e = (*i).second; edevice.openTag(SUMO_TAG_EDGE); edevice.writeAttr(SUMO_ATTR_ID, e->getID()); edevice.writeAttr(SUMO_ATTR_FROM, e->getFromNode()->getID()); edevice.writeAttr(SUMO_ATTR_TO, e->getToNode()->getID()); if (!noNames && e->getStreetName() != "") { edevice.writeAttr(SUMO_ATTR_NAME, StringUtils::escapeXML(e->getStreetName())); } edevice.writeAttr(SUMO_ATTR_PRIORITY, e->getPriority()); // write the type if given if (e->getTypeID() != "") { edevice.writeAttr(SUMO_ATTR_TYPE, e->getTypeID()); } edevice.writeAttr(SUMO_ATTR_NUMLANES, e->getNumLanes()); if (!e->hasLaneSpecificSpeed()) { edevice.writeAttr(SUMO_ATTR_SPEED, e->getSpeed()); } // write non-default geometry if (!e->hasDefaultGeometry()) { PositionVector geom = e->getGeometry(); if (useGeo) { for (int i = 0; i < (int) geom.size(); i++) { gch.cartesian2geo(geom[i]); } } if (geoAccuracy) { edevice.setPrecision(GEO_OUTPUT_ACCURACY); } edevice.writeAttr(SUMO_ATTR_SHAPE, geom); if (geoAccuracy) { edevice.setPrecision(); } } // write the spread type if not default ("right") if (e->getLaneSpreadFunction() != LANESPREAD_RIGHT) { edevice.writeAttr(SUMO_ATTR_SPREADTYPE, toString(e->getLaneSpreadFunction())); } // write the length if it was specified if (e->hasLoadedLength()) { edevice.writeAttr(SUMO_ATTR_LENGTH, e->getLoadedLength()); } // some attributes can be set by edge default or per lane. Write as default if possible (efficiency) if (e->getLaneWidth() != NBEdge::UNSPECIFIED_WIDTH && !e->hasLaneSpecificWidth()) { edevice.writeAttr(SUMO_ATTR_WIDTH, e->getLaneWidth()); } if (e->getOffset() != NBEdge::UNSPECIFIED_OFFSET && !e->hasLaneSpecificOffset()) { edevice.writeAttr(SUMO_ATTR_OFFSET, e->getOffset()); } if (!e->needsLaneSpecificOutput()) { edevice.closeTag(); } else { for (unsigned int i = 0; i < e->getLanes().size(); ++i) { const NBEdge::Lane& lane = e->getLanes()[i]; edevice.openTag(SUMO_TAG_LANE); edevice.writeAttr(SUMO_ATTR_INDEX, i); // write allowed lanes NWWriter_SUMO::writePermissions(edevice, lane.permissions); NWWriter_SUMO::writePreferences(edevice, lane.preferred); // write other attributes if (lane.width != NBEdge::UNSPECIFIED_WIDTH && e->hasLaneSpecificWidth()) { edevice.writeAttr(SUMO_ATTR_WIDTH, lane.width); } if (lane.offset != NBEdge::UNSPECIFIED_OFFSET && e->hasLaneSpecificOffset()) { edevice.writeAttr(SUMO_ATTR_OFFSET, lane.offset); } if (e->hasLaneSpecificSpeed()) { edevice.writeAttr(SUMO_ATTR_SPEED, lane.speed); } edevice.closeTag(); } edevice.closeTag(); } // write this edge's connections to the connections-files e->sortOutgoingConnectionsByIndex(); const std::vector<NBEdge::Connection> connections = e->getConnections(); for (std::vector<NBEdge::Connection>::const_iterator c = connections.begin(); c != connections.end(); ++c) { NWWriter_SUMO::writeConnection(cdevice, *e, *c, false, NWWriter_SUMO::PLAIN); } if (connections.size() > 0) { cdevice << "\n"; } } // write loaded prohibitions to the connections-file for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { NWWriter_SUMO::writeProhibitions(cdevice, i->second->getProhibitions()); } edevice.close(); cdevice.close(); }