void NWWriter_XML::writeNodes(const OptionsCont& oc, NBNodeCont& nc) { const GeoConvHelper& gch = GeoConvHelper::getFinal(); bool useGeo = oc.exists("proj.plain-geo") && oc.getBool("proj.plain-geo"); if (useGeo && !gch.usingGeoProjection()) { WRITE_WARNING("Ignoring option \"proj.plain-geo\" because no geo-conversion has been defined"); useGeo = false; } const bool geoAccuracy = useGeo || gch.usingInverseGeoProjection(); OutputDevice& device = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".nod.xml"); device.writeXMLHeader("nodes", NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/nodes_file.xsd\""); // write network offsets and projection to allow reconstruction of original coordinates if (!useGeo) { NWWriter_SUMO::writeLocation(device); } // write nodes for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { NBNode* n = (*i).second; device.openTag(SUMO_TAG_NODE); device.writeAttr(SUMO_ATTR_ID, n->getID()); // write position Position pos = n->getPosition(); if (useGeo) { gch.cartesian2geo(pos); } if (geoAccuracy) { device.setPrecision(GEO_OUTPUT_ACCURACY); } NWFrame::writePositionLong(pos, device); if (geoAccuracy) { device.setPrecision(); } device.writeAttr(SUMO_ATTR_TYPE, toString(n->getType())); if (n->isTLControlled()) { const std::set<NBTrafficLightDefinition*>& tlss = n->getControllingTLS(); // set may contain multiple programs for the same id. // make sure ids are unique and sorted std::set<std::string> tlsIDs; for (std::set<NBTrafficLightDefinition*>::const_iterator it_tl = tlss.begin(); it_tl != tlss.end(); it_tl++) { tlsIDs.insert((*it_tl)->getID()); } std::vector<std::string> sortedIDs(tlsIDs.begin(), tlsIDs.end()); sort(sortedIDs.begin(), sortedIDs.end()); device.writeAttr(SUMO_ATTR_TLID, sortedIDs); } device.closeTag(); } device.close(); }
void NBNodeCont::discardTrafficLights(NBTrafficLightLogicCont& tlc, bool geometryLike) { for (NodeCont::const_iterator i = myNodes.begin(); i != myNodes.end(); ++i) { NBNode* node = i->second; if (!geometryLike || node->geometryLike()) { // make a copy of tldefs const std::set<NBTrafficLightDefinition*> tldefs = node->getControllingTLS(); for (std::set<NBTrafficLightDefinition*>::const_iterator it = tldefs.begin(); it != tldefs.end(); ++it) { NBTrafficLightDefinition* tlDef = *it; node->removeTrafficLight(tlDef); tlc.extract(tlDef); } node->reinit(node->getPosition(), NODETYPE_UNKNOWN); } } }
void GNENet::computeJunction(GNEJunction* junction) { // recompute tl-logics OptionsCont& oc = OptionsCont::getOptions(); NBTrafficLightLogicCont& tllCont = getTLLogicCont(); NBNode* nbn = junction->getNBNode(); std::set<NBTrafficLightDefinition*> tldefs = nbn->getControllingTLS(); for (std::set<NBTrafficLightDefinition*>::iterator it = tldefs.begin(); it != tldefs.end(); it++) { NBTrafficLightDefinition* def = *it; def->setParticipantsInformation(); def->setTLControllingInformation(); tllCont.computeSingleLogic(oc, def); } // @todo compute connections etc... }
void GNETLSEditorFrame::initDefinitions() { myDefinitions.clear(); myDefBox->clearItems(); assert(myCurrentJunction); NBNode* nbn = myCurrentJunction->getNBNode(); std::set<NBTrafficLightDefinition*> tldefs = nbn->getControllingTLS(); for (std::set<NBTrafficLightDefinition*>::iterator it = tldefs.begin(); it != tldefs.end(); it++) { myDefinitions.push_back(*it); std::string item = (*it)->getID() + ", " + (*it)->getProgramID(); myDefBox->appendItem(item.c_str()); } if (myDefinitions.size() > 0) { myDefBox->setCurrentItem(0); myDefBox->setNumVisible(myDefBox->getNumItems()); myDefBox->show(); onCmdDefSwitch(0, 0, 0); } updateDescription(); }
void NBNodeCont::discardTrafficLights(NBTrafficLightLogicCont& tlc, bool geometryLike, bool guessSignals) { for (NodeCont::const_iterator i = myNodes.begin(); i != myNodes.end(); ++i) { NBNode* node = i->second; if (!geometryLike || node->geometryLike()) { // make a copy of tldefs const std::set<NBTrafficLightDefinition*> tldefs = node->getControllingTLS(); if (guessSignals && node->isTLControlled() && node->geometryLike()) { // record signal location const EdgeVector& outgoing = node->getOutgoingEdges(); for (EdgeVector::const_iterator it_o = outgoing.begin(); it_o != outgoing.end(); ++it_o) { (*it_o)->setSignalOffset((*it_o)->getLength()); } } for (std::set<NBTrafficLightDefinition*>::const_iterator it = tldefs.begin(); it != tldefs.end(); ++it) { NBTrafficLightDefinition* tlDef = *it; node->removeTrafficLight(tlDef); tlc.extract(tlDef); } node->reinit(node->getPosition(), NODETYPE_UNKNOWN); } } }
void NBNodeCont::guessTLs(OptionsCont& oc, NBTrafficLightLogicCont& tlc) { // build list of definitely not tls-controlled junctions std::vector<NBNode*> ncontrolled; if (oc.isSet("tls.unset")) { std::vector<std::string> notTLControlledNodes = oc.getStringVector("tls.unset"); for (std::vector<std::string>::const_iterator i = notTLControlledNodes.begin(); i != notTLControlledNodes.end(); ++i) { NBNode* n = NBNodeCont::retrieve(*i); if (n == 0) { throw ProcessError(" The node '" + *i + "' to set as not-controlled is not known."); } std::set<NBTrafficLightDefinition*> tls = n->getControllingTLS(); for (std::set<NBTrafficLightDefinition*>::const_iterator j = tls.begin(); j != tls.end(); ++j) { (*j)->removeNode(n); } n->removeTrafficLights(); ncontrolled.push_back(n); } } TrafficLightType type = SUMOXMLDefinitions::TrafficLightTypes.get(OptionsCont::getOptions().getString("tls.default-type")); // loop#1 checking whether the node shall be tls controlled, // because it is assigned to a district if (oc.exists("tls.taz-nodes") && oc.getBool("tls.taz-nodes")) { for (NodeCont::iterator i = myNodes.begin(); i != myNodes.end(); i++) { NBNode* cur = (*i).second; if (cur->isNearDistrict() && find(ncontrolled.begin(), ncontrolled.end(), cur) == ncontrolled.end()) { setAsTLControlled(cur, tlc, type); } } } // maybe no tls shall be guessed if (!oc.getBool("tls.guess")) { return; } // guess joined tls first, if wished if (oc.getBool("tls.join")) { // get node clusters std::vector<std::set<NBNode*> > cands; generateNodeClusters(oc.getFloat("tls.join-dist"), cands); // check these candidates (clusters) whether they should be controlled by a tls for (std::vector<std::set<NBNode*> >::iterator i = cands.begin(); i != cands.end();) { std::set<NBNode*>& c = (*i); // regard only junctions which are not yet controlled and are not // forbidden to be controlled for (std::set<NBNode*>::iterator j = c.begin(); j != c.end();) { if ((*j)->isTLControlled() || find(ncontrolled.begin(), ncontrolled.end(), *j) != ncontrolled.end()) { c.erase(j++); } else { ++j; } } // check whether the cluster should be controlled if (!shouldBeTLSControlled(c)) { i = cands.erase(i); } else { ++i; } } // cands now only contain sets of junctions that shall be joined into being tls-controlled unsigned int index = 0; for (std::vector<std::set<NBNode*> >::iterator i = cands.begin(); i != cands.end(); ++i) { std::vector<NBNode*> nodes; for (std::set<NBNode*>::iterator j = (*i).begin(); j != (*i).end(); j++) { nodes.push_back(*j); } std::string id = "joinedG_" + toString(index++); NBTrafficLightDefinition* tlDef = new NBOwnTLDef(id, nodes, 0, type); if (!tlc.insert(tlDef)) { // actually, nothing should fail here WRITE_WARNING("Could not build guessed, joined tls"); delete tlDef; return; } } } // guess tls for (NodeCont::iterator i = myNodes.begin(); i != myNodes.end(); i++) { NBNode* cur = (*i).second; // do nothing if already is tl-controlled if (cur->isTLControlled()) { continue; } // do nothing if in the list of explicit non-controlled junctions if (find(ncontrolled.begin(), ncontrolled.end(), cur) != ncontrolled.end()) { continue; } std::set<NBNode*> c; c.insert(cur); if (!shouldBeTLSControlled(c) || cur->getIncomingEdges().size() < 3) { continue; } setAsTLControlled((*i).second, tlc, type); } }
// =========================================================================== // 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(); }
void NBNodeCont::guessTLs(OptionsCont& oc, NBTrafficLightLogicCont& tlc) { // build list of definitely not tls-controlled junctions std::vector<NBNode*> ncontrolled; if (oc.isSet("tls.unset")) { std::vector<std::string> notTLControlledNodes = oc.getStringVector("tls.unset"); for (std::vector<std::string>::const_iterator i = notTLControlledNodes.begin(); i != notTLControlledNodes.end(); ++i) { NBNode* n = NBNodeCont::retrieve(*i); if (n == 0) { throw ProcessError(" The node '" + *i + "' to set as not-controlled is not known."); } std::set<NBTrafficLightDefinition*> tls = n->getControllingTLS(); for (std::set<NBTrafficLightDefinition*>::const_iterator j = tls.begin(); j != tls.end(); ++j) { (*j)->removeNode(n); } n->removeTrafficLights(); ncontrolled.push_back(n); } } TrafficLightType type = SUMOXMLDefinitions::TrafficLightTypes.get(OptionsCont::getOptions().getString("tls.default-type")); // loop#1 checking whether the node shall be tls controlled, // because it is assigned to a district if (oc.exists("tls.taz-nodes") && oc.getBool("tls.taz-nodes")) { for (NodeCont::iterator i = myNodes.begin(); i != myNodes.end(); i++) { NBNode* cur = (*i).second; if (cur->isNearDistrict() && find(ncontrolled.begin(), ncontrolled.end(), cur) == ncontrolled.end()) { setAsTLControlled(cur, tlc, type); } } } // figure out which nodes mark the locations of TLS signals // This assumes nodes are already joined if (oc.exists("tls.guess-signals") && oc.getBool("tls.guess-signals")) { // prepare candidate edges const SUMOReal signalDist = oc.getFloat("tls.guess-signals.dist"); for (std::map<std::string, NBNode*>::const_iterator i = myNodes.begin(); i != myNodes.end(); ++i) { NBNode* node = (*i).second; if (node->isTLControlled() && node->geometryLike()) { const EdgeVector& outgoing = node->getOutgoingEdges(); for (EdgeVector::const_iterator it_o = outgoing.begin(); it_o != outgoing.end(); ++it_o) { (*it_o)->setSignalOffset((*it_o)->getLength()); } } } // check which nodes should be controlled for (std::map<std::string, NBNode*>::const_iterator i = myNodes.begin(); i != myNodes.end(); ++i) { NBNode* node = i->second; const EdgeVector& incoming = node->getIncomingEdges(); if (!node->isTLControlled() && incoming.size() > 1 && !node->geometryLike()) { std::vector<NBNode*> signals; bool isTLS = true; for (EdgeVector::const_iterator it_i = incoming.begin(); it_i != incoming.end(); ++it_i) { const NBEdge* inEdge = *it_i; if (inEdge->getSignalOffset() == NBEdge::UNSPECIFIED_SIGNAL_OFFSET || inEdge->getSignalOffset() > signalDist) { isTLS = false; break; } if (inEdge->getSignalOffset() == inEdge->getLength()) { signals.push_back(inEdge->getFromNode()); } } if (isTLS) { for (std::vector<NBNode*>::iterator j = signals.begin(); j != signals.end(); ++j) { std::set<NBTrafficLightDefinition*> tls = (*j)->getControllingTLS(); (*j)->removeTrafficLights(); for (std::set<NBTrafficLightDefinition*>::iterator k = tls.begin(); k != tls.end(); ++k) { tlc.removeFully((*j)->getID()); } } NBTrafficLightDefinition* tlDef = new NBOwnTLDef("GS_" + node->getID(), node, 0, TLTYPE_STATIC); // @todo patch endOffset for all incoming lanes according to the signal positions if (!tlc.insert(tlDef)) { // actually, nothing should fail here WRITE_WARNING("Could not build joined tls '" + node->getID() + "'."); delete tlDef; return; } } } } } // maybe no tls shall be guessed if (!oc.getBool("tls.guess")) { return; } // guess joined tls first, if wished if (oc.getBool("tls.join")) { // get node clusters std::vector<std::set<NBNode*> > cands; generateNodeClusters(oc.getFloat("tls.join-dist"), cands); // check these candidates (clusters) whether they should be controlled by a tls for (std::vector<std::set<NBNode*> >::iterator i = cands.begin(); i != cands.end();) { std::set<NBNode*>& c = (*i); // regard only junctions which are not yet controlled and are not // forbidden to be controlled for (std::set<NBNode*>::iterator j = c.begin(); j != c.end();) { if ((*j)->isTLControlled() || find(ncontrolled.begin(), ncontrolled.end(), *j) != ncontrolled.end()) { c.erase(j++); } else { ++j; } } // check whether the cluster should be controlled if (!shouldBeTLSControlled(c)) { i = cands.erase(i); } else { ++i; } } // cands now only contain sets of junctions that shall be joined into being tls-controlled unsigned int index = 0; for (std::vector<std::set<NBNode*> >::iterator i = cands.begin(); i != cands.end(); ++i) { std::vector<NBNode*> nodes; for (std::set<NBNode*>::iterator j = (*i).begin(); j != (*i).end(); j++) { nodes.push_back(*j); } std::string id = "joinedG_" + toString(index++); NBTrafficLightDefinition* tlDef = new NBOwnTLDef(id, nodes, 0, type); if (!tlc.insert(tlDef)) { // actually, nothing should fail here WRITE_WARNING("Could not build guessed, joined tls"); delete tlDef; return; } } } // guess tls for (NodeCont::iterator i = myNodes.begin(); i != myNodes.end(); i++) { NBNode* cur = (*i).second; // do nothing if already is tl-controlled if (cur->isTLControlled()) { continue; } // do nothing if in the list of explicit non-controlled junctions if (find(ncontrolled.begin(), ncontrolled.end(), cur) != ncontrolled.end()) { continue; } std::set<NBNode*> c; c.insert(cur); if (!shouldBeTLSControlled(c) || cur->getIncomingEdges().size() < 3) { continue; } setAsTLControlled((*i).second, tlc, type); } }