long GNEConnectorFrame::onCmdSelectDeadStarts(FXObject*, FXSelector, void*) { GNENet* net = myViewNet->getNet(); std::set<GUIGlID> selectIDs; // every edge knows only its outgoing connections so we look at whole junctions const std::vector<GNEJunction*> junctions = net->retrieveJunctions(); for (std::vector<GNEJunction*>::const_iterator junction_it = junctions.begin(); junction_it != junctions.end(); junction_it++) { // first collect all outgoing lanes const EdgeVector& outgoing = (*junction_it)->getNBNode()->getOutgoingEdges(); for (EdgeVector::const_iterator it = outgoing.begin(); it != outgoing.end(); it++) { GNEEdge* edge = net->retrieveEdge((*it)->getID()); const std::set<GUIGlID> laneIDs = edge->getLaneGlIDs(); for (std::set<GUIGlID>::const_iterator lid_it = laneIDs.begin(); lid_it != laneIDs.end(); lid_it++) { selectIDs.insert(*lid_it); } } // then remove all approached lanes const EdgeVector& incoming = (*junction_it)->getNBNode()->getIncomingEdges(); for (EdgeVector::const_iterator it = incoming.begin(); it != incoming.end(); it++) { GNEEdge* edge = net->retrieveEdge((*it)->getID()); NBEdge* nbe = edge->getNBEdge(); const std::vector<NBEdge::Connection>& connections = nbe->getConnections(); for (std::vector<NBEdge::Connection>::const_iterator con_it = connections.begin(); con_it != connections.end(); con_it++) { GNEEdge* approachedEdge = net->retrieveEdge(con_it->toEdge->getID()); GNELane* approachedLane = approachedEdge->getLanes()[con_it->toLane]; selectIDs.erase(approachedLane->getGlID()); } } } myViewNet->getViewParent()->getSelectorFrame()->handleIDs( std::vector<GUIGlID>(selectIDs.begin(), selectIDs.end()), false, GNESelectorFrame::SET_REPLACE); return 1; }
long GNEConnectorFrame::onCmdSelectConflicts(FXObject*, FXSelector, void*) { std::vector<GUIGlID> selectIDs; // conflicts happen per edge so we can look at each edge in isolation const std::vector<GNEEdge*> edges = myViewNet->getNet()->retrieveEdges(); for (std::vector<GNEEdge*>::const_iterator edge_it = edges.begin(); edge_it != edges.end(); edge_it++) { NBEdge* nbe = (*edge_it)->getNBEdge(); const EdgeVector destinations = nbe->getConnectedEdges(); const std::vector<NBEdge::Connection>& connections = nbe->getConnections(); for (EdgeVector::const_iterator dest_it = destinations.begin(); dest_it != destinations.end(); dest_it++) { GNEEdge* dest = myViewNet->getNet()->retrieveEdge((*dest_it)->getID()); const GNEEdge::LaneVector& destLanes = dest->getLanes(); for (GNEEdge::LaneVector::const_iterator it_lane = destLanes.begin(); it_lane != destLanes.end(); it_lane++) { const bool isConflicted = count_if( connections.begin(), connections.end(), NBEdge::connections_toedgelane_finder(*dest_it, (int)(*it_lane)->getIndex(), -1)) > 1; if (isConflicted) { selectIDs.push_back((*it_lane)->getGlID()); } } } } myViewNet->getViewParent()->getSelectorFrame()->handleIDs(selectIDs, false, GNESelectorFrame::SET_REPLACE); return 1; }
void GNEJunction::setLogicValid(bool valid, GNEUndoList* undoList, const std::string& status) { myHasValidLogic = valid; if (!valid) { assert(undoList != 0); assert(undoList->hasCommandGroup()); undoList->add(new GNEChange_Attribute(this, GNE_ATTR_MODIFICATION_STATUS, status)); // allow edges to recompute their connections NBTurningDirectionsComputer::computeTurnDirectionsForNode(&myNBNode, false); EdgeVector incoming = EdgeVector(myNBNode.getIncomingEdges()); for (EdgeVector::iterator it = incoming.begin(); it != incoming.end(); it++) { NBEdge* srcNBE = *it; NBEdge* turnEdge = srcNBE->getTurnDestination(); GNEEdge* srcEdge = myNet->retrieveEdge(srcNBE->getID()); std::vector<NBEdge::Connection> connections = srcNBE->getConnections(); // make a copy! // delete in reverse so that undoing will add connections in the original order for (std::vector<NBEdge::Connection>::reverse_iterator con_it = connections.rbegin(); con_it != connections.rend(); con_it++) { bool hasTurn = con_it->toEdge == turnEdge; undoList->add(new GNEChange_Connection( srcEdge, con_it->fromLane, con_it->toEdge->getID(), con_it->toLane, con_it->mayDefinitelyPass, false), true); // needs to come after GNEChange_Connection // XXX bug: this code path will not be used on a redo! if (hasTurn) { myNet->addExplicitTurnaround(srcNBE->getID()); } } undoList->add(new GNEChange_Attribute(srcEdge, GNE_ATTR_MODIFICATION_STATUS, status), true); } invalidateTLS(undoList); } else { rebuildCrossings(false); } }
void NWWriter_DlrNavteq::writeConnectedLanes(const OptionsCont& oc, NBNodeCont& nc) { OutputDevice& device = OutputDevice::getDevice(oc.getString("dlr-navteq-output") + "_connected_lanes.txt"); writeHeader(device, oc); // write format specifier device << "#Lane connections related to LINK-IDs and NODE-ID.\n"; device << "#column format like pointcollection.\n"; device << "#NODE-ID\tVEHICLE-TYPE\tFROM_LANE\tTO_LANE\tTHROUGH_TRAFFIC\tLINK_IDs[2..*]\n"; // write record for every connection for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { NBNode* n = (*i).second; const EdgeVector& incoming = n->getIncomingEdges(); for (EdgeVector::const_iterator j = incoming.begin(); j != incoming.end(); ++j) { NBEdge* from = *j; const SVCPermissions fromPerm = from->getPermissions(); const std::vector<NBEdge::Connection>& connections = from->getConnections(); for (std::vector<NBEdge::Connection>::const_iterator it_c = connections.begin(); it_c != connections.end(); it_c++) { const NBEdge::Connection& c = *it_c; device << n->getID() << "\t" << getAllowedTypes(fromPerm & c.toEdge->getPermissions()) << "\t" << c.fromLane + 1 << "\t" // one-based << c.toLane + 1 << "\t" // one-based << 1 << "\t" // no information regarding permissibility of through traffic << from->getID() << "\t" << c.toEdge->getID() << "\t" << "\n"; } } } device.close(); }
void NIXMLTrafficLightsHandler::addTlConnection(const SUMOSAXAttributes& attrs) { bool ok = true; // parse identifying attributes NBEdge* from = retrieveEdge(attrs, SUMO_ATTR_FROM, ok); NBEdge* to = retrieveEdge(attrs, SUMO_ATTR_TO, ok); if (!ok) { return; } int fromLane = retrieveLaneIndex(attrs, SUMO_ATTR_FROM_LANE, from, ok); int toLane = retrieveLaneIndex(attrs, SUMO_ATTR_TO_LANE, to, ok); if (!ok) { return; } // retrieve connection const std::vector<NBEdge::Connection>& connections = from->getConnections(); std::vector<NBEdge::Connection>::const_iterator con_it; con_it = find_if(connections.begin(), connections.end(), NBEdge::connections_finder(fromLane, to, toLane)); if (con_it == connections.end()) { WRITE_ERROR("Connection from=" + from->getID() + " to=" + to->getID() + " fromLane=" + toString(fromLane) + " toLane=" + toString(toLane) + " not found"); return; } NBEdge::Connection c = *con_it; // read other attributes std::string tlID = attrs.getOptStringReporting(SUMO_ATTR_TLID, 0, ok, ""); if (tlID == "") { // we are updating an existing tl-controlled connection tlID = c.tlID; assert(tlID != ""); } int tlIndex = attrs.getOptIntReporting(SUMO_ATTR_TLLINKINDEX, 0, ok, -1); if (tlIndex == -1) { // we are updating an existing tl-controlled connection tlIndex = c.tlLinkNo; } // register the connection with all definitions const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(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(from, c.toEdge, c.fromLane, c.toLane, tlIndex); } else { throw ProcessError("Corrupt traffic light definition '" + tlID + "' (program '" + it->first + "')"); } } } else { WRITE_ERROR("The traffic light '" + tlID + "' is not known."); } }
long GNEConnectorFrame::onCmdSelectPass(FXObject*, FXSelector, void*) { std::vector<GUIGlID> selectIDs; const std::vector<GNEEdge*> edges = myViewNet->getNet()->retrieveEdges(); for (std::vector<GNEEdge*>::const_iterator edge_it = edges.begin(); edge_it != edges.end(); edge_it++) { GNEEdge* edge = *edge_it; NBEdge* nbe = edge->getNBEdge(); const std::vector<NBEdge::Connection>& connections = nbe->getConnections(); for (std::vector<NBEdge::Connection>::const_iterator it = connections.begin(); it != connections.end(); ++it) { if (it->mayDefinitelyPass) { GNELane* lane = edge->getLanes()[it->fromLane]; selectIDs.push_back(lane->getGlID()); } } } myViewNet->getViewParent()->getSelectorFrame()->handleIDs(selectIDs, false, GNESelectorFrame::SET_REPLACE); return 1; }
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 NWWriter_XML::writeTrafficLights(const OptionsCont& oc, NBTrafficLightLogicCont& tc, NBEdgeCont& ec) { OutputDevice& device = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".tll.xml"); device.writeXMLHeader("tlLogics", NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/tllogic_file.xsd\""); NWWriter_SUMO::writeTrafficLights(device, tc); // we also need to remember the associations between tlLogics and connections // since the information in con.xml is insufficient for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) { NBEdge* e = (*i).second; // write this edge's tl-controlled connections const std::vector<NBEdge::Connection> connections = e->getConnections(); for (std::vector<NBEdge::Connection>::const_iterator c = connections.begin(); c != connections.end(); ++c) { if (c->tlID != "") { NWWriter_SUMO::writeConnection(device, *e, *c, false, NWWriter_SUMO::TLL); } } } device.close(); }
bool NWWriter_SUMO::writeInternalConnections(OutputDevice& into, const NBNode& n) { bool ret = false; const std::vector<NBEdge*>& incoming = n.getIncomingEdges(); for (std::vector<NBEdge*>::const_iterator i = incoming.begin(); i != incoming.end(); ++i) { NBEdge* from = *i; const std::vector<NBEdge::Connection>& connections = from->getConnections(); for (std::vector<NBEdge::Connection>::const_iterator j = connections.begin(); j != connections.end(); ++j) { const NBEdge::Connection& c = *j; assert(c.toEdge != 0); if (c.haveVia) { // internal split writeInternalConnection(into, c.id, c.toEdge->getID(), c.internalLaneIndex, c.toLane, c.viaID + "_0"); writeInternalConnection(into, c.viaID, c.toEdge->getID(), 0, c.toLane, ""); } else { // no internal split writeInternalConnection(into, c.id, c.toEdge->getID(), c.internalLaneIndex, c.toLane, ""); } ret = true; } } return ret; }
void NBTurningDirectionsComputer::computeTurnDirectionsForNode(NBNode* node) { const std::vector<NBEdge*>& incoming = node->getIncomingEdges(); const std::vector<NBEdge*>& outgoing = node->getOutgoingEdges(); std::vector<Combination> combinations; for (std::vector<NBEdge*>::const_iterator j = outgoing.begin(); j != outgoing.end(); ++j) { NBEdge* outedge = *j; for (std::vector<NBEdge*>::const_iterator k = incoming.begin(); k != incoming.end(); ++k) { NBEdge* e = *k; if (e->getConnections().size() != 0 && !e->isConnectedTo(outedge)) { // has connections, but not to outedge; outedge will not be the turn direction // // @todo: this seems to be needed due to legacy issues; actually, we could regard // such pairs, too, and it probably would increase the accuracy. But there is // no mechanism implemented, yet, which would avoid adding them as turnarounds though // no connection is specified. continue; } // @todo: check whether NBHelpers::relAngle is properly defined and whether it should really be used, here SUMOReal angle = fabs(NBHelpers::relAngle(e->getAngleAtNode(node), outedge->getAngleAtNode(node))); if (angle < 160) { continue; } if (e->getFromNode() == outedge->getToNode()) { // they connect the same nodes; should be the turnaround direction // we'll assign a maximum number // // @todo: indeed, we have observed some pathological intersections // see "294831560" in OSM/adlershof. Here, several edges are connecting // same nodes. We have to do the angle check before... // // @todo: and well, there are some other as well, see plain import // of delphi_muenchen (elmar), intersection "59534191". Not that it would // be realistic in any means; we will warn, here. angle += 360; } Combination c; c.from = e; c.to = outedge; c.angle = angle; combinations.push_back(c); } } // sort combinations so that the ones with the highest angle are at the begin std::sort(combinations.begin(), combinations.end(), combination_by_angle_sorter()); std::set<NBEdge*> seen; bool haveWarned = false; for (std::vector<Combination>::const_iterator j = combinations.begin(); j != combinations.end(); ++j) { if (seen.find((*j).from) != seen.end() || seen.find((*j).to) != seen.end()) { // do not regard already set edges if ((*j).angle > 360 && !haveWarned) { WRITE_WARNING("Ambiguity in turnarounds computation at node '" + node->getID() + "'."); haveWarned = true; } continue; } // mark as seen seen.insert((*j).from); seen.insert((*j).to); // set turnaround information (*j).from->setTurningDestination((*j).to); } }
void NBNodeCont::joinNodeClusters(NodeClusters clusters, NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tlc) { for (NodeClusters::iterator i = clusters.begin(); i != clusters.end(); ++i) { std::set<NBNode*> cluster = *i; assert(cluster.size() > 1); Position pos; bool setTL; std::string id; TrafficLightType type; analyzeCluster(cluster, id, pos, setTL, type); if (!insert(id, pos)) { // should not fail WRITE_WARNING("Could not join junctions " + id); continue; } NBNode* newNode = retrieve(id); if (setTL) { NBTrafficLightDefinition* tlDef = new NBOwnTLDef(id, newNode, 0, type); if (!tlc.insert(tlDef)) { // actually, nothing should fail here delete tlDef; throw ProcessError("Could not allocate tls '" + id + "'."); } } // collect edges std::set<NBEdge*> allEdges; for (std::set<NBNode*>::const_iterator j = cluster.begin(); j != cluster.end(); ++j) { const EdgeVector& edges = (*j)->getEdges(); allEdges.insert(edges.begin(), edges.end()); } // remap and remove edges which are completely within the new intersection for (std::set<NBEdge*>::iterator j = allEdges.begin(); j != allEdges.end();) { NBEdge* e = (*j); NBNode* from = e->getFromNode(); NBNode* to = e->getToNode(); if (cluster.count(from) > 0 && cluster.count(to) > 0) { for (std::set<NBEdge*>::iterator l = allEdges.begin(); l != allEdges.end(); ++l) { if (e != *l) { (*l)->replaceInConnections(e, e->getConnections()); } } ec.erase(dc, e); allEdges.erase(j++); // erase does not invalidate the other iterators } else { ++j; } } // remap edges which are incoming / outgoing for (std::set<NBEdge*>::iterator j = allEdges.begin(); j != allEdges.end(); ++j) { NBEdge* e = (*j); std::vector<NBEdge::Connection> conns = e->getConnections(); const bool outgoing = cluster.count(e->getFromNode()) > 0; NBNode* from = outgoing ? newNode : e->getFromNode(); NBNode* to = outgoing ? e->getToNode() : newNode; e->reinitNodes(from, to); // re-add connections which previously existed and may still valid. // connections to removed edges will be ignored for (std::vector<NBEdge::Connection>::iterator k = conns.begin(); k != conns.end(); ++k) { e->addLane2LaneConnection((*k).fromLane, (*k).toEdge, (*k).toLane, NBEdge::L2L_USER, false, (*k).mayDefinitelyPass); } } // remove original nodes registerJoinedCluster(cluster); for (std::set<NBNode*>::const_iterator j = cluster.begin(); j != cluster.end(); ++j) { erase(*j); } } }
// =========================================================================== // method definitions // =========================================================================== // --------------------------------------------------------------------------- // static methods // --------------------------------------------------------------------------- void NWWriter_SUMO::writeNetwork(const OptionsCont& oc, NBNetBuilder& nb) { // check whether a sumo net-file shall be generated if (!oc.isSet("output-file")) { return; } OutputDevice& device = OutputDevice::getDevice(oc.getString("output-file")); const std::string lefthand = oc.getBool("lefthand") ? " " + toString(SUMO_ATTR_LEFTHAND) + "=\"true\"" : ""; const int cornerDetail = oc.getInt("junctions.corner-detail"); const int linkDetail = oc.getInt("junctions.internal-link-detail"); const std::string junctionCornerDetail = (cornerDetail > 0 ? " " + toString(SUMO_ATTR_CORNERDETAIL) + "=\"" + toString(cornerDetail) + "\"" : ""); const std::string junctionLinkDetail = (oc.isDefault("junctions.internal-link-detail") ? "" : " " + toString(SUMO_ATTR_LINKDETAIL) + "=\"" + toString(linkDetail) + "\""); device.writeXMLHeader("net", NWFrame::MAJOR_VERSION + lefthand + junctionCornerDetail + junctionLinkDetail + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.dlr.de/xsd/net_file.xsd\""); // street names may contain non-ascii chars device.lf(); // get involved container const NBNodeCont& nc = nb.getNodeCont(); const NBEdgeCont& ec = nb.getEdgeCont(); const NBDistrictCont& dc = nb.getDistrictCont(); // write network offsets and projection GeoConvHelper::writeLocation(device); // write edge types and restrictions nb.getTypeCont().writeTypes(device); // write inner lanes bool origNames = oc.getBool("output.original-names"); if (!oc.getBool("no-internal-links")) { bool hadAny = false; for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { hadAny |= writeInternalEdges(device, *(*i).second, origNames); } if (hadAny) { device.lf(); } } // write edges with lanes and connected edges bool noNames = !oc.getBool("output.street-names"); for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) { writeEdge(device, *(*i).second, noNames, origNames); } device.lf(); // write tls logics writeTrafficLights(device, nb.getTLLogicCont()); // write the nodes (junctions) std::set<NBNode*> roundaboutNodes; const bool checkLaneFoesAll = oc.getBool("check-lane-foes.all"); const bool checkLaneFoesRoundabout = !checkLaneFoesAll && oc.getBool("check-lane-foes.roundabout"); if (checkLaneFoesRoundabout) { const std::set<EdgeSet>& roundabouts = ec.getRoundabouts(); for (std::set<EdgeSet>::const_iterator i = roundabouts.begin(); i != roundabouts.end(); ++i) { for (EdgeSet::const_iterator j = (*i).begin(); j != (*i).end(); ++j) { roundaboutNodes.insert((*j)->getToNode()); } } } for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { const bool checkLaneFoes = checkLaneFoesAll || (checkLaneFoesRoundabout && roundaboutNodes.count((*i).second) > 0); writeJunction(device, *(*i).second, checkLaneFoes); } device.lf(); const bool includeInternal = !oc.getBool("no-internal-links"); if (includeInternal) { // ... internal nodes if not unwanted bool hadAny = false; for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { hadAny |= writeInternalNodes(device, *(*i).second); } if (hadAny) { device.lf(); } } // write the successors of lanes unsigned int numConnections = 0; for (std::map<std::string, NBEdge*>::const_iterator it_edge = ec.begin(); it_edge != ec.end(); it_edge++) { NBEdge* from = it_edge->second; from->sortOutgoingConnectionsByIndex(); const std::vector<NBEdge::Connection> connections = from->getConnections(); numConnections += (unsigned int)connections.size(); for (std::vector<NBEdge::Connection>::const_iterator it_c = connections.begin(); it_c != connections.end(); it_c++) { writeConnection(device, *from, *it_c, includeInternal); } } if (numConnections > 0) { device.lf(); } if (includeInternal) { // ... internal successors if not unwanted bool hadAny = false; for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { hadAny |= writeInternalConnections(device, *(*i).second); } if (hadAny) { device.lf(); } } for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { NBNode* node = (*i).second; // write connections from pedestrian crossings const std::vector<NBNode::Crossing>& crossings = node->getCrossings(); for (std::vector<NBNode::Crossing>::const_iterator it = crossings.begin(); it != crossings.end(); it++) { NWWriter_SUMO::writeInternalConnection(device, (*it).id, (*it).nextWalkingArea, 0, 0, ""); } // write connections from pedestrian walking areas const std::vector<NBNode::WalkingArea>& WalkingAreas = node->getWalkingAreas(); for (std::vector<NBNode::WalkingArea>::const_iterator it = WalkingAreas.begin(); it != WalkingAreas.end(); it++) { if ((*it).nextCrossing != "") { const NBNode::Crossing& nextCrossing = node->getCrossing((*it).nextCrossing); // connection to next crossing (may be tls-controlled) device.openTag(SUMO_TAG_CONNECTION); device.writeAttr(SUMO_ATTR_FROM, (*it).id); device.writeAttr(SUMO_ATTR_TO, (*it).nextCrossing); device.writeAttr(SUMO_ATTR_FROM_LANE, 0); device.writeAttr(SUMO_ATTR_TO_LANE, 0); if (node->isTLControlled()) { device.writeAttr(SUMO_ATTR_TLID, (*node->getControllingTLS().begin())->getID()); assert(nextCrossing.tlLinkNo >= 0); device.writeAttr(SUMO_ATTR_TLLINKINDEX, nextCrossing.tlLinkNo); } device.writeAttr(SUMO_ATTR_DIR, LINKDIR_STRAIGHT); device.writeAttr(SUMO_ATTR_STATE, nextCrossing.priority ? LINKSTATE_MAJOR : LINKSTATE_MINOR); device.closeTag(); } // optional connections from/to sidewalk for (std::vector<std::string>::const_iterator it_sw = (*it).nextSidewalks.begin(); it_sw != (*it).nextSidewalks.end(); ++it_sw) { NWWriter_SUMO::writeInternalConnection(device, (*it).id, (*it_sw), 0, 0, ""); } for (std::vector<std::string>::const_iterator it_sw = (*it).prevSidewalks.begin(); it_sw != (*it).prevSidewalks.end(); ++it_sw) { NWWriter_SUMO::writeInternalConnection(device, (*it_sw), (*it).id, 0, 0, ""); } } } // write loaded prohibitions for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { writeProhibitions(device, i->second->getProhibitions()); } // write roundabout information writeRoundabouts(device, ec.getRoundabouts(), ec); // write the districts for (std::map<std::string, NBDistrict*>::const_iterator i = dc.begin(); i != dc.end(); i++) { writeDistrict(device, *(*i).second); } if (dc.size() != 0) { device.lf(); } device.close(); }
// =========================================================================== // method definitions // =========================================================================== // --------------------------------------------------------------------------- // static methods // --------------------------------------------------------------------------- void NWWriter_SUMO::writeNetwork(const OptionsCont& oc, NBNetBuilder& nb) { // check whether a sumo net-file shall be generated if (!oc.isSet("output-file")) { return; } OutputDevice& device = OutputDevice::getDevice(oc.getString("output-file")); device.writeXMLHeader("net", NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.sf.net/xsd/net_file.xsd\""); // street names may contain non-ascii chars device.lf(); // get involved container const NBNodeCont& nc = nb.getNodeCont(); const NBEdgeCont& ec = nb.getEdgeCont(); const NBDistrictCont& dc = nb.getDistrictCont(); // write network offsets and projection writeLocation(device); // write inner lanes bool origNames = oc.getBool("output.original-names"); if (!oc.getBool("no-internal-links")) { bool hadAny = false; for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { hadAny |= writeInternalEdges(device, *(*i).second, origNames); } if (hadAny) { device.lf(); } } // write edges with lanes and connected edges bool noNames = !oc.getBool("output.street-names"); for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) { writeEdge(device, *(*i).second, noNames, origNames); } device.lf(); // write tls logics writeTrafficLights(device, nb.getTLLogicCont()); // write the nodes (junctions) for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { writeJunction(device, *(*i).second); } device.lf(); const bool includeInternal = !oc.getBool("no-internal-links"); if (includeInternal) { // ... internal nodes if not unwanted bool hadAny = false; for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { hadAny |= writeInternalNodes(device, *(*i).second); } if (hadAny) { device.lf(); } } // write the successors of lanes unsigned int numConnections = 0; for (std::map<std::string, NBEdge*>::const_iterator it_edge = ec.begin(); it_edge != ec.end(); it_edge++) { NBEdge* from = it_edge->second; from->sortOutgoingConnectionsByIndex(); const std::vector<NBEdge::Connection> connections = from->getConnections(); numConnections += (unsigned int)connections.size(); for (std::vector<NBEdge::Connection>::const_iterator it_c = connections.begin(); it_c != connections.end(); it_c++) { writeConnection(device, *from, *it_c, includeInternal); } } if (numConnections > 0) { device.lf(); } if (includeInternal) { // ... internal successors if not unwanted bool hadAny = false; for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { hadAny |= writeInternalConnections(device, *(*i).second); } if (hadAny) { device.lf(); } } // write loaded prohibitions for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { writeProhibitions(device, i->second->getProhibitions()); } // write roundabout information const std::vector<EdgeVector>& roundabouts = nb.getRoundabouts(); for (std::vector<EdgeVector>::const_iterator i = roundabouts.begin(); i != roundabouts.end(); ++i) { writeRoundabout(device, *i); } if (roundabouts.size() != 0) { device.lf(); } // write the districts for (std::map<std::string, NBDistrict*>::const_iterator i = dc.begin(); i != dc.end(); i++) { writeDistrict(device, *(*i).second); } if (dc.size() != 0) { device.lf(); } device.close(); }
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(); }