void NBHeightMapper::loadIfSet(OptionsCont& oc) { if (oc.isSet("heightmap.geotiff")) { // parse file(s) std::vector<std::string> files = oc.getStringVector("heightmap.geotiff"); for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) { PROGRESS_BEGIN_MESSAGE("Parsing from GeoTIFF '" + *file + "'"); int numFeatures = Singleton.loadTiff(*file); MsgHandler::getMessageInstance()->endProcessMsg( " done (parsed " + toString(numFeatures) + " features, Boundary: " + toString(Singleton.getBoundary()) + ")."); } } if (oc.isSet("heightmap.shapefiles")) { // parse file(s) std::vector<std::string> files = oc.getStringVector("heightmap.shapefiles"); for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) { PROGRESS_BEGIN_MESSAGE("Parsing from shape-file '" + *file + "'"); int numFeatures = Singleton.loadShapeFile(*file); MsgHandler::getMessageInstance()->endProcessMsg( " done (parsed " + toString(numFeatures) + " features, Boundary: " + toString(Singleton.getBoundary()) + ")."); } } }
void loadJTRDefinitions(RONet& net, OptionsCont& oc) { // load the turning definitions (and possible sink definition) if (oc.isSet("turn-ratio-files")) { ROJTRTurnDefLoader loader(net); std::vector<std::string> ratio_files = oc.getStringVector("turn-ratio-files"); for (std::vector<std::string>::const_iterator i = ratio_files.begin(); i != ratio_files.end(); ++i) { if (!XMLSubSys::runParser(loader, *i)) { throw ProcessError(); } } } if (MsgHandler::getErrorInstance()->wasInformed() && oc.getBool("ignore-errors")) { MsgHandler::getErrorInstance()->clear(); } // parse sink edges specified at the input/within the configuration if (oc.isSet("sink-edges")) { std::vector<std::string> edges = oc.getStringVector("sink-edges"); for (std::vector<std::string>::const_iterator i = edges.begin(); i != edges.end(); ++i) { ROJTREdge* edge = static_cast<ROJTREdge*>(net.getEdge(*i)); if (edge == 0) { throw ProcessError("The edge '" + *i + "' declared as a sink is not known."); } edge->setSink(); } } }
/* ------------------------------------------------------------------------- * file loading methods * ----------------------------------------------------------------------- */ void NILoader::loadXML(OptionsCont& oc) { // load nodes loadXMLType(new NIXMLNodesHandler(myNetBuilder.getNodeCont(), myNetBuilder.getTLLogicCont(), oc), oc.getStringVector("node-files"), "nodes"); // load the edges loadXMLType(new NIXMLEdgesHandler(myNetBuilder.getNodeCont(), myNetBuilder.getEdgeCont(), myNetBuilder.getTypeCont(), myNetBuilder.getDistrictCont(), myNetBuilder.getTLLogicCont(), oc), oc.getStringVector("edge-files"), "edges"); if (!deprecatedVehicleClassesSeen.empty()) { WRITE_WARNING("Deprecated vehicle class(es) '" + toString(deprecatedVehicleClassesSeen) + "' in input edge files."); } // load the connections loadXMLType(new NIXMLConnectionsHandler(myNetBuilder.getEdgeCont(), myNetBuilder.getTLLogicCont()), oc.getStringVector("connection-files"), "connections"); // load traffic lights (needs to come last, references loaded edges and connections) loadXMLType(new NIXMLTrafficLightsHandler( myNetBuilder.getTLLogicCont(), myNetBuilder.getEdgeCont()), oc.getStringVector("tllogic-files"), "traffic lights"); }
void NBTrafficLightLogicCont::applyOptions(OptionsCont &oc) throw() { // check whether any offsets shall be manipulated by setting // them to half of the duration if (oc.isSet("tl-logics.half-offset")) { myHalfOffsetTLS = oc.getStringVector("tl-logics.half-offset"); } // check whether any offsets shall be manipulated by setting // them to a quarter of the duration if (oc.isSet("tl-logics.quarter-offset")) { myQuarterOffsetTLS = oc.getStringVector("tl-logics.quarter-offset"); } }
void NBTrafficLightLogicCont::applyOptions(OptionsCont& oc) { // check whether any offsets shall be manipulated by setting // them to half of the duration if (oc.isSet("tls.half-offset")) { std::vector<std::string> ids = oc.getStringVector("tls.half-offset"); myHalfOffsetTLS.insert(ids.begin(), ids.end()); } // check whether any offsets shall be manipulated by setting // them to a quarter of the duration if (oc.isSet("tls.quarter-offset")) { std::vector<std::string> ids = oc.getStringVector("tls.quarter-offset"); myHalfOffsetTLS.insert(ids.begin(), ids.end()); } }
void MSBaseVehicle::initMoveReminderOutput(const OptionsCont& oc) { if (oc.isSet("movereminder-output.vehicles")) { const std::vector<std::string> vehicles = oc.getStringVector("movereminder-output.vehicles"); myShallTraceMoveReminders.insert(vehicles.begin(), vehicles.end()); } }
// =========================================================================== // method definitions // =========================================================================== // --------------------------------------------------------------------------- // static methods // --------------------------------------------------------------------------- void NIImporter_MATSim::loadNetwork(const OptionsCont& oc, NBNetBuilder& nb) { // check whether the option is set (properly) if (!oc.isSet("matsim-files")) { return; } /* Parse file(s) * Each file is parsed twice: first for nodes, second for edges. */ std::vector<std::string> files = oc.getStringVector("matsim-files"); // load nodes, first NodesHandler nodesHandler(nb.getNodeCont()); for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) { // nodes if (!FileHelpers::isReadable(*file)) { WRITE_ERROR("Could not open matsim-file '" + *file + "'."); return; } nodesHandler.setFileName(*file); PROGRESS_BEGIN_MESSAGE("Parsing nodes from matsim-file '" + *file + "'"); if (!XMLSubSys::runParser(nodesHandler, *file)) { return; } PROGRESS_DONE_MESSAGE(); } // load edges, then EdgesHandler edgesHandler(nb.getNodeCont(), nb.getEdgeCont(), oc.getBool("matsim.keep-length"), oc.getBool("matsim.lanes-from-capacity"), NBCapacity2Lanes(oc.getFloat("lanes-from-capacity.norm"))); for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) { // edges edgesHandler.setFileName(*file); PROGRESS_BEGIN_MESSAGE("Parsing edges from matsim-file '" + *file + "'"); XMLSubSys::runParser(edgesHandler, *file); PROGRESS_DONE_MESSAGE(); } }
// =========================================================================== // method definitions // =========================================================================== // --------------------------------------------------------------------------- // static methods (interface in this case) // --------------------------------------------------------------------------- void NIImporter_RobocupRescue::loadNetwork(const OptionsCont& oc, NBNetBuilder& nb) { // check whether the option is set (properly) if (!oc.isSet("robocup-dir")) { return; } // build the handler NIImporter_RobocupRescue handler(nb.getNodeCont(), nb.getEdgeCont()); // parse file(s) std::vector<std::string> files = oc.getStringVector("robocup-dir"); for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) { // nodes std::string nodesName = (*file) + "/node.bin"; if (!FileHelpers::exists(nodesName)) { WRITE_ERROR("Could not open robocup-node-file '" + nodesName + "'."); return; } PROGRESS_BEGIN_MESSAGE("Parsing robocup-nodes from '" + nodesName + "'"); handler.loadNodes(nodesName); PROGRESS_DONE_MESSAGE(); // edges std::string edgesName = (*file) + "/road.bin"; if (!FileHelpers::exists(edgesName)) { WRITE_ERROR("Could not open robocup-road-file '" + edgesName + "'."); return; } PROGRESS_BEGIN_MESSAGE("Parsing robocup-roads from '" + edgesName + "'"); handler.loadEdges(edgesName); PROGRESS_DONE_MESSAGE(); } }
// =========================================================================== // method definitions // =========================================================================== // --------------------------------------------------------------------------- // static methods // --------------------------------------------------------------------------- void NIImporter_ITSUMO::loadNetwork(const OptionsCont& oc, NBNetBuilder& nb) { // check whether the option is set (properly) if (!oc.isSet("itsumo-files")) { return; } /* Parse file(s) * Each file is parsed twice: first for nodes, second for edges. */ std::vector<std::string> files = oc.getStringVector("itsumo-files"); // load nodes, first Handler Handler(nb); for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) { // nodes if (!FileHelpers::exists(*file)) { WRITE_ERROR("Could not open itsumo-file '" + *file + "'."); return; } Handler.setFileName(*file); PROGRESS_BEGIN_MESSAGE("Parsing nodes from itsumo-file '" + *file + "'"); if (!XMLSubSys::runParser(Handler, *file)) { return; } PROGRESS_DONE_MESSAGE(); } }
// =========================================================================== // method definitions // =========================================================================== // --------------------------------------------------------------------------- // NBRampsComputer // --------------------------------------------------------------------------- void NBRampsComputer::computeRamps(NBNetBuilder& nb, OptionsCont& oc) { SUMOReal minHighwaySpeed = oc.getFloat("ramps.min-highway-speed"); SUMOReal maxRampSpeed = oc.getFloat("ramps.max-ramp-speed"); SUMOReal rampLength = oc.getFloat("ramps.ramp-length"); bool dontSplit = oc.getBool("ramps.no-split"); std::set<NBEdge*> incremented; // check whether on-off ramps shall be guessed if (oc.getBool("ramps.guess")) { NBNodeCont& nc = nb.getNodeCont(); NBEdgeCont& ec = nb.getEdgeCont(); NBDistrictCont& dc = nb.getDistrictCont(); std::set<NBNode*> potOnRamps; std::set<NBNode*> potOffRamps; for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { NBNode* cur = (*i).second; if (mayNeedOnRamp(cur, minHighwaySpeed, maxRampSpeed)) { potOnRamps.insert(cur); } if (mayNeedOffRamp(cur, minHighwaySpeed, maxRampSpeed)) { potOffRamps.insert(cur); } } for (std::set<NBNode*>::const_iterator i = potOnRamps.begin(); i != potOnRamps.end(); ++i) { buildOnRamp(*i, nc, ec, dc, rampLength, dontSplit, incremented); } for (std::set<NBNode*>::const_iterator i = potOffRamps.begin(); i != potOffRamps.end(); ++i) { buildOffRamp(*i, nc, ec, dc, rampLength, dontSplit, incremented); } } // check whether on-off ramps shall be guessed if (oc.isSet("ramps.set")) { std::vector<std::string> edges = oc.getStringVector("ramps.set"); NBNodeCont& nc = nb.getNodeCont(); NBEdgeCont& ec = nb.getEdgeCont(); NBDistrictCont& dc = nb.getDistrictCont(); for (std::vector<std::string>::iterator i = edges.begin(); i != edges.end(); ++i) { NBEdge* e = ec.retrieve(*i); if (e == 0) { WRITE_WARNING("Can not build on ramp on edge '" + *i + "' - the edge is not known."); continue; } NBNode* from = e->getFromNode(); if (from->getIncomingEdges().size() == 2 && from->getOutgoingEdges().size() == 1) { buildOnRamp(from, nc, ec, dc, rampLength, dontSplit, incremented); } // load edge again to check offramps e = ec.retrieve(*i); if (e == 0) { WRITE_WARNING("Can not build off ramp on edge '" + *i + "' - the edge is not known."); continue; } NBNode* to = e->getToNode(); if (to->getIncomingEdges().size() == 1 && to->getOutgoingEdges().size() == 2) { buildOffRamp(to, nc, ec, dc, rampLength, dontSplit, incremented); } } } }
void ODMatrix::loadMatrix(OptionsCont& oc) { std::vector<std::string> files = oc.getStringVector("od-matrix-files"); for (std::vector<std::string>::iterator i = files.begin(); i != files.end(); ++i) { LineReader lr(*i); if (!lr.good()) { throw ProcessError("Could not open '" + (*i) + "'."); } std::string type = lr.readLine(); // get the type only if (type.find(';') != std::string::npos) { type = type.substr(0, type.find(';')); } // parse type-dependant if (type.length() > 1 && type[1] == 'V') { // process ptv's 'V'-matrices if (type.find('N') != std::string::npos) { throw ProcessError("'" + *i + "' does not contain the needed information about the time described."); } readV(lr, oc.getFloat("scale"), oc.getString("vtype"), type.find('M') != std::string::npos); } else if (type.length() > 1 && type[1] == 'O') { // process ptv's 'O'-matrices if (type.find('N') != std::string::npos) { throw ProcessError("'" + *i + "' does not contain the needed information about the time described."); } readO(lr, oc.getFloat("scale"), oc.getString("vtype"), type.find('M') != std::string::npos); } else { throw ProcessError("'" + *i + "' uses an unknown matrix type '" + type + "'."); } } std::vector<std::string> amitranFiles = oc.getStringVector("od-amitran-files"); for (std::vector<std::string>::iterator i = amitranFiles.begin(); i != amitranFiles.end(); ++i) { if (!FileHelpers::isReadable(*i)) { throw ProcessError("Could not access matrix file '" + *i + "' to load."); } PROGRESS_BEGIN_MESSAGE("Loading matrix in Amitran format from '" + *i + "'"); ODAmitranHandler handler(*this, *i); if (!XMLSubSys::runParser(handler, *i)) { PROGRESS_FAILED_MESSAGE(); } else { PROGRESS_DONE_MESSAGE(); } } }
void NILoader::load(OptionsCont& oc) { // load types first NIXMLTypesHandler* handler = new NIXMLTypesHandler(myNetBuilder.getTypeCont()); loadXMLType(handler, oc.getStringVector("type-files"), "types"); // try to load height data so it is ready for use by other importers #ifdef HAVE_INTERNAL HeightMapper::loadIfSet(oc); #endif // try to load using different methods NIImporter_SUMO::loadNetwork(oc, myNetBuilder); NIImporter_RobocupRescue::loadNetwork(oc, myNetBuilder); NIImporter_OpenStreetMap::loadNetwork(oc, myNetBuilder); NIImporter_VISUM::loadNetwork(oc, myNetBuilder); NIImporter_ArcView::loadNetwork(oc, myNetBuilder); NIImporter_Vissim::loadNetwork(oc, myNetBuilder); NIImporter_DlrNavteq::loadNetwork(oc, myNetBuilder); NIImporter_OpenDrive::loadNetwork(oc, myNetBuilder); NIImporter_MATSim::loadNetwork(oc, myNetBuilder); NIImporter_ITSUMO::loadNetwork(oc, myNetBuilder); if (oc.getBool("tls.discard-loaded") || oc.getBool("tls.discard-simple")) { myNetBuilder.getNodeCont().discardTrafficLights(myNetBuilder.getTLLogicCont(), oc.getBool("tls.discard-simple"), oc.getBool("tls.guess-signals")); size_t removed = myNetBuilder.getTLLogicCont().getNumExtracted(); if (removed > 0) { WRITE_MESSAGE(" Removed " + toString(removed) + " traffic lights before loading plain-XML"); } } loadXML(oc); // check the loaded structures if (myNetBuilder.getNodeCont().size() == 0) { throw ProcessError("No nodes loaded."); } if (myNetBuilder.getEdgeCont().size() == 0) { throw ProcessError("No edges loaded."); } // report loaded structures WRITE_MESSAGE(" Import done:"); if (myNetBuilder.getDistrictCont().size() > 0) { WRITE_MESSAGE(" " + toString(myNetBuilder.getDistrictCont().size()) + " districts loaded."); } WRITE_MESSAGE(" " + toString(myNetBuilder.getNodeCont().size()) + " nodes loaded."); if (myNetBuilder.getTypeCont().size() > 0) { WRITE_MESSAGE(" " + toString(myNetBuilder.getTypeCont().size()) + " types loaded."); } WRITE_MESSAGE(" " + toString(myNetBuilder.getEdgeCont().size()) + " edges loaded."); if (myNetBuilder.getEdgeCont().getNoEdgeSplits() > 0) { WRITE_MESSAGE("The split of edges was performed " + toString(myNetBuilder.getEdgeCont().getNoEdgeSplits()) + " times."); } if (GeoConvHelper::getProcessing().usingGeoProjection()) { WRITE_MESSAGE("Proj projection parameters used: '" + GeoConvHelper::getProcessing().getProjString() + "'."); } }
/* ------------------------------------------------------------------------- * file loading methods * ----------------------------------------------------------------------- */ void NILoader::loadXML(OptionsCont& oc) { // load nodes loadXMLType(new NIXMLNodesHandler(myNetBuilder.getNodeCont(), myNetBuilder.getTLLogicCont(), oc), oc.getStringVector("node-files"), "nodes"); // load the edges loadXMLType(new NIXMLEdgesHandler(myNetBuilder.getNodeCont(), myNetBuilder.getEdgeCont(), myNetBuilder.getTypeCont(), myNetBuilder.getDistrictCont(), myNetBuilder.getTLLogicCont(), oc), oc.getStringVector("edge-files"), "edges"); // load the connections loadXMLType(new NIXMLConnectionsHandler(myNetBuilder.getEdgeCont(), myNetBuilder.getTLLogicCont()), oc.getStringVector("connection-files"), "connections"); // load traffic lights (needs to come last, references loaded edges and connections) loadXMLType(new NIXMLTrafficLightsHandler( myNetBuilder.getTLLogicCont(), myNetBuilder.getEdgeCont()), oc.getStringVector("tllogic-files"), "traffic lights"); }
void PCLoaderDlrNavteq::loadPolyFiles(OptionsCont& oc, PCPolyContainer& toFill, PCTypeMap& tm) { std::vector<std::string> files = oc.getStringVector("dlr-navteq-poly-files"); for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) { if (!FileHelpers::isReadable(*file)) { throw ProcessError("Could not open dlr-navteq-poly-file '" + *file + "'."); } PROGRESS_BEGIN_MESSAGE("Parsing pois from dlr-navteq-poly-file '" + *file + "'"); loadPolyFile(*file, oc, toFill, tm); PROGRESS_DONE_MESSAGE(); } }
// =========================================================================== // method definitions // =========================================================================== void PCLoaderArcView::loadIfSet(OptionsCont& oc, PCPolyContainer& toFill, PCTypeMap& tm) { if (!oc.isSet("shapefile-prefixes")) { return; } // parse file(s) std::vector<std::string> files = oc.getStringVector("shapefile-prefixes"); for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) { PROGRESS_BEGIN_MESSAGE("Parsing from shape-file '" + *file + "'"); load(*file, oc, toFill, tm); PROGRESS_DONE_MESSAGE(); } }
void ODMatrix::loadRoutes(OptionsCont& oc, SUMOSAXHandler& handler) { std::vector<std::string> routeFiles = oc.getStringVector("route-files"); for (std::vector<std::string>::iterator i = routeFiles.begin(); i != routeFiles.end(); ++i) { if (!FileHelpers::isReadable(*i)) { throw ProcessError("Could not access route file '" + *i + "' to load."); } PROGRESS_BEGIN_MESSAGE("Loading routes and trips from '" + *i + "'"); if (!XMLSubSys::runParser(handler, *i)) { PROGRESS_FAILED_MESSAGE(); } else { PROGRESS_DONE_MESSAGE(); } } }
std::vector<double> getTurningDefaults(OptionsCont& oc) { std::vector<double> ret; std::vector<std::string> defs = oc.getStringVector("turn-defaults"); if (defs.size() < 2) { throw ProcessError("The defaults for turnings must be a tuple of at least two numbers divided by ','."); } for (std::vector<std::string>::const_iterator i = defs.begin(); i != defs.end(); ++i) { try { double val = TplConvert::_2double((*i).c_str()); ret.push_back(val); } catch (NumberFormatException&) { throw ProcessError("A turn default is not numeric."); } } return ret; }
// =========================================================================== // method definitions // =========================================================================== void PCLoaderVisum::loadIfSet(OptionsCont& oc, PCPolyContainer& toFill, PCTypeMap& tm) { if (!oc.isSet("visum-files")) { return; } // parse file(s) std::vector<std::string> files = oc.getStringVector("visum-files"); for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) { if (!FileHelpers::exists(*file)) { throw ProcessError("Could not open visum-file '" + *file + "'."); } PROGRESS_BEGIN_MESSAGE("Parsing from visum-file '" + *file + "'"); load(*file, oc, toFill, tm); PROGRESS_DONE_MESSAGE(); } }
void readDetectorFlows(RODFDetectorFlows& flows, OptionsCont& oc, RODFDetectorCon& dc) { if (!oc.isSet("measure-files")) { // ok, not given, return an empty container return; } // check whether the file exists std::vector<std::string> files = oc.getStringVector("measure-files"); for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) { if (!FileHelpers::exists(*fileIt)) { throw ProcessError("The measure-file '" + *fileIt + "' can not be opened."); } // parse PROGRESS_BEGIN_MESSAGE("Loading flows from '" + *fileIt + "'"); RODFDetFlowLoader dfl(dc, flows, string2time(oc.getString("begin")), string2time(oc.getString("end")), string2time(oc.getString("time-offset")), string2time(oc.getString("time-factor"))); dfl.read(*fileIt); PROGRESS_DONE_MESSAGE(); } }
// =========================================================================== // method definitions // =========================================================================== // --------------------------------------------------------------------------- // static interface // --------------------------------------------------------------------------- void PCLoaderXML::loadIfSet(OptionsCont& oc, PCPolyContainer& toFill, PCTypeMap& tm) { if (!oc.isSet("xml-files")) { return; } PCLoaderXML handler(toFill, tm, oc); // parse file(s) std::vector<std::string> files = oc.getStringVector("xml"); for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) { if (!FileHelpers::isReadable(*file)) { throw ProcessError("Could not open xml-file '" + *file + "'."); } PROGRESS_BEGIN_MESSAGE("Parsing XML from '" + *file + "'"); if (!XMLSubSys::runParser(handler, *file)) { throw ProcessError(); } PROGRESS_DONE_MESSAGE(); } }
/* ------------------------------------------------------------------------- * data processing methods * ----------------------------------------------------------------------- */ void readDetectors(RODFDetectorCon& detectors, OptionsCont& oc, RODFNet* optNet) { if (!oc.isSet("detector-files")) { throw ProcessError("No detector file given (use --detector-files <FILE>)."); } // read definitions stored in XML-format std::vector<std::string> files = oc.getStringVector("detector-files"); for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) { if (!FileHelpers::exists(*fileIt)) { throw ProcessError("Could not open detector file '" + *fileIt + "'"); } PROGRESS_BEGIN_MESSAGE("Loading detector definitions from '" + *fileIt + "'"); RODFDetectorHandler handler(optNet, oc.getBool("ignore-invalid-detectors"), detectors, *fileIt); if (XMLSubSys::runParser(handler, *fileIt)) { PROGRESS_DONE_MESSAGE(); } else { PROGRESS_FAILED_MESSAGE(); throw ProcessError(); } } if (detectors.getDetectors().empty()) { throw ProcessError("No detectors found."); } }
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); } }
void NIImporter_OpenStreetMap::_loadNetwork(const OptionsCont& oc, NBNetBuilder& nb) { // check whether the option is set (properly) if (!oc.isSet("osm-files")) { return; } // preset types // for highways NBTypeCont& tc = nb.getTypeCont(); SUMOReal const WIDTH = NBEdge::UNSPECIFIED_WIDTH; tc.insert("highway.motorway", 3, (SUMOReal)(160./ 3.6), 13, WIDTH, SVC_UNKNOWN, true); tc.insert("highway.motorway_link", 1, (SUMOReal)(80. / 3.6), 12, WIDTH, SVC_UNKNOWN, true); tc.insert("highway.trunk", 2, (SUMOReal)(100./ 3.6), 11, WIDTH); // !!! 130km/h? tc.insert("highway.trunk_link", 1, (SUMOReal)(80. / 3.6), 10, WIDTH); tc.insert("highway.primary", 2, (SUMOReal)(100./ 3.6), 9, WIDTH); tc.insert("highway.primary_link", 1, (SUMOReal)(80. / 3.6), 8, WIDTH); tc.insert("highway.secondary", 2, (SUMOReal)(100./ 3.6), 7, WIDTH); tc.insert("highway.secondary_link",1, (SUMOReal)(80. / 3.6), 6, WIDTH); tc.insert("highway.tertiary", 1, (SUMOReal)(80. / 3.6), 6, WIDTH); tc.insert("highway.tertiary_link", 1, (SUMOReal)(80. / 3.6), 5, WIDTH); tc.insert("highway.unclassified", 1, (SUMOReal)(80. / 3.6), 5, WIDTH); tc.insert("highway.residential", 1, (SUMOReal)(50. / 3.6), 4, WIDTH); // actually, maybe one lane for parking would be nice... tc.insert("highway.living_street", 1, (SUMOReal)(10. / 3.6), 3, WIDTH); tc.insert("highway.service", 1, (SUMOReal)(20. / 3.6), 2, WIDTH, SVC_DELIVERY); tc.insert("highway.track", 1, (SUMOReal)(20. / 3.6), 1, WIDTH); tc.insert("highway.services", 1, (SUMOReal)(30. / 3.6), 1, WIDTH); tc.insert("highway.unsurfaced", 1, (SUMOReal)(30. / 3.6), 1, WIDTH); // unofficial value, used outside germany tc.insert("highway.footway", 1, (SUMOReal)(30. / 3.6), 1, WIDTH, SVC_PEDESTRIAN); tc.insert("highway.pedestrian", 1, (SUMOReal)(30. / 3.6), 1, WIDTH, SVC_PEDESTRIAN); tc.insert("highway.path", 1, (SUMOReal)(10. / 3.6), 1, WIDTH, SVC_PEDESTRIAN); tc.insert("highway.bridleway", 1, (SUMOReal)(10. / 3.6), 1, WIDTH, SVC_BICYCLE); // no horse stuff tc.insert("highway.cycleway", 1, (SUMOReal)(20. / 3.6), 1, WIDTH, SVC_BICYCLE); tc.insert("highway.footway", 1, (SUMOReal)(10. / 3.6), 1, WIDTH, SVC_PEDESTRIAN); tc.insert("highway.step", 1, (SUMOReal)(5. / 3.6), 1, WIDTH, SVC_PEDESTRIAN); // additional tc.insert("highway.steps", 1, (SUMOReal)(5. / 3.6), 1, WIDTH, SVC_PEDESTRIAN); // :-) do not run too fast tc.insert("highway.stairs", 1, (SUMOReal)(5. / 3.6), 1, WIDTH, SVC_PEDESTRIAN); // additional tc.insert("highway.bus_guideway", 1, (SUMOReal)(30. / 3.6), 1, WIDTH, SVC_BUS); tc.insert("highway.raceway", 2, (SUMOReal)(300./ 3.6), 14, WIDTH, SVC_VIP); tc.insert("highway.ford", 1, (SUMOReal)(10. / 3.6), 1, WIDTH, SVC_PUBLIC_ARMY); // for railways tc.insert("railway.rail", 1, (SUMOReal)(30. / 3.6), 1, WIDTH, SVC_RAIL_FAST); tc.insert("railway.tram", 1, (SUMOReal)(30. / 3.6), 1, WIDTH, SVC_CITYRAIL); tc.insert("railway.light_rail", 1, (SUMOReal)(30. / 3.6), 1, WIDTH, SVC_LIGHTRAIL); tc.insert("railway.subway", 1, (SUMOReal)(30. / 3.6), 1, WIDTH, SVC_CITYRAIL); tc.insert("railway.preserved", 1, (SUMOReal)(30. / 3.6), 1, WIDTH, SVC_LIGHTRAIL); tc.insert("railway.monorail", 1, (SUMOReal)(30. / 3.6), 1, WIDTH, SVC_LIGHTRAIL); // rail stuff has to be discussed /* Parse file(s) * Each file is parsed twice: first for nodes, second for edges. */ std::vector<std::string> files = oc.getStringVector("osm-files"); // load nodes, first NodesHandler nodesHandler(myOSMNodes, myUniqueNodes); for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) { // nodes if (!FileHelpers::exists(*file)) { WRITE_ERROR("Could not open osm-file '" + *file + "'."); return; } nodesHandler.setFileName(*file); PROGRESS_BEGIN_MESSAGE("Parsing nodes from osm-file '" + *file + "'"); if (!XMLSubSys::runParser(nodesHandler, *file)) { return; } PROGRESS_DONE_MESSAGE(); } // load edges, then EdgesHandler edgesHandler(myOSMNodes, myEdges); for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) { // edges edgesHandler.setFileName(*file); PROGRESS_BEGIN_MESSAGE("Parsing edges from osm-file '" + *file + "'"); XMLSubSys::runParser(edgesHandler, *file); PROGRESS_DONE_MESSAGE(); } /* Remove duplicate edges with the same shape and attributes */ if (!OptionsCont::getOptions().getBool("osm.skip-duplicates-check")) { PROGRESS_BEGIN_MESSAGE("Removing duplicate edges"); if (myEdges.size() > 1) { std::set<const Edge*, CompareEdges> dupsFinder; for (std::map<std::string, Edge*>::iterator it = myEdges.begin(); it != myEdges.end();) { if (dupsFinder.count(it->second) > 0) { WRITE_MESSAGE("Found duplicate edges. Removing " + it->first); delete it->second; myEdges.erase(it++); } else { dupsFinder.insert(it->second); it++; } } } PROGRESS_DONE_MESSAGE(); } /* Mark which nodes are used (by edges or traffic lights). * This is necessary to detect which OpenStreetMap nodes are for * geometry only */ std::map<int, int> nodeUsage; // Mark which nodes are used by edges (begin and end) for (std::map<std::string, Edge*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) { Edge* e = (*i).second; assert(e->myCurrentIsRoad); for (std::vector<int>::const_iterator j = e->myCurrentNodes.begin(); j != e->myCurrentNodes.end(); ++j) { if (nodeUsage.find(*j) == nodeUsage.end()) { nodeUsage[*j] = 0; } nodeUsage[*j] = nodeUsage[*j] + 1; } } // Mark which nodes are used by traffic lights for (std::map<int, NIOSMNode*>::const_iterator nodesIt = myOSMNodes.begin(); nodesIt != myOSMNodes.end(); ++nodesIt) { if (nodesIt->second->tlsControlled) { // If the key is not found in the map, the value is automatically // initialized with 0. nodeUsage[nodesIt->first] += 1; } } /* Instantiate edges * Only those nodes in the middle of an edge which are used by more than * one edge are instantiated. Other nodes are considered as geometry nodes. */ NBNodeCont& nc = nb.getNodeCont(); NBEdgeCont& ec = nb.getEdgeCont(); NBTrafficLightLogicCont& tlsc = nb.getTLLogicCont(); for (std::map<std::string, Edge*>::iterator i = myEdges.begin(); i != myEdges.end(); ++i) { Edge* e = (*i).second; assert(e->myCurrentIsRoad); // build nodes; // the from- and to-nodes must be built in any case // the geometry nodes are only built if more than one edge references them NBNode* currentFrom = insertNodeChecking(*e->myCurrentNodes.begin(), nc, tlsc); NBNode* last = insertNodeChecking(*(e->myCurrentNodes.end() - 1), nc, tlsc); int running = 0; std::vector<int> passed; for (std::vector<int>::iterator j = e->myCurrentNodes.begin(); j != e->myCurrentNodes.end(); ++j) { passed.push_back(*j); if (nodeUsage[*j] > 1 && j != e->myCurrentNodes.end() - 1 && j != e->myCurrentNodes.begin()) { NBNode* currentTo = insertNodeChecking(*j, nc, tlsc); insertEdge(e, running, currentFrom, currentTo, passed, ec, tc); currentFrom = currentTo; running++; passed.clear(); } } if (running == 0) { running = -1; } insertEdge(e, running, currentFrom, last, passed, ec, tc); } }
void NBEdgeCont::applyOptions(OptionsCont& oc) { myAmLeftHanded = oc.getBool("lefthand"); // set edges dismiss/accept options myEdgesMinSpeed = oc.isSet("keep-edges.min-speed") ? oc.getFloat("keep-edges.min-speed") : -1; myRemoveEdgesAfterJoining = oc.exists("keep-edges.postload") && oc.getBool("keep-edges.postload"); if (oc.isSet("keep-edges.explicit")) { const std::vector<std::string> edges = oc.getStringVector("keep-edges.explicit"); myEdges2Keep.insert(edges.begin(), edges.end()); } if (oc.isSet("remove-edges.explicit")) { const std::vector<std::string> edges = oc.getStringVector("remove-edges.explicit"); myEdges2Remove.insert(edges.begin(), edges.end()); } if (oc.exists("keep-edges.by-vclass") && oc.isSet("keep-edges.by-vclass")) { const std::vector<std::string> classes = oc.getStringVector("keep-edges.by-vclass"); for (std::vector<std::string>::const_iterator i = classes.begin(); i != classes.end(); ++i) { myVehicleClasses2Keep |= getVehicleClassID(*i); } } if (oc.exists("remove-edges.by-vclass") && oc.isSet("remove-edges.by-vclass")) { const std::vector<std::string> classes = oc.getStringVector("remove-edges.by-vclass"); for (std::vector<std::string>::const_iterator i = classes.begin(); i != classes.end(); ++i) { myVehicleClasses2Remove |= getVehicleClassID(*i); } } if (oc.exists("keep-edges.by-type") && oc.isSet("keep-edges.by-type")) { const std::vector<std::string> types = oc.getStringVector("keep-edges.by-type"); myTypes2Keep.insert(types.begin(), types.end()); } if (oc.exists("remove-edges.by-type") && oc.isSet("remove-edges.by-type")) { const std::vector<std::string> types = oc.getStringVector("remove-edges.by-type"); myTypes2Remove.insert(types.begin(), types.end()); } if (oc.isSet("keep-edges.in-boundary") || oc.isSet("keep-edges.in-geo-boundary")) { std::vector<std::string> polyS = oc.getStringVector(oc.isSet("keep-edges.in-boundary") ? "keep-edges.in-boundary" : "keep-edges.in-geo-boundary"); // !!! throw something if length<4 || length%2!=0? std::vector<SUMOReal> poly; for (std::vector<std::string>::iterator i = polyS.begin(); i != polyS.end(); ++i) { poly.push_back(TplConvert::_2SUMOReal((*i).c_str())); // !!! may throw something anyhow... } if (poly.size() < 4) { throw ProcessError("Invalid boundary: need at least 2 coordinates"); } else if (poly.size() % 2 != 0) { throw ProcessError("Invalid boundary: malformed coordinate"); } else if (poly.size() == 4) { // prunning boundary (box) myPrunningBoundary.push_back(Position(poly[0], poly[1])); myPrunningBoundary.push_back(Position(poly[2], poly[1])); myPrunningBoundary.push_back(Position(poly[2], poly[3])); myPrunningBoundary.push_back(Position(poly[0], poly[3])); } else { for (std::vector<SUMOReal>::iterator j = poly.begin(); j != poly.end();) { SUMOReal x = *j++; SUMOReal y = *j++; myPrunningBoundary.push_back(Position(x, y)); } } if (oc.isSet("keep-edges.in-geo-boundary")) { NBNetBuilder::transformCoordinates(myPrunningBoundary, false); } } }
void NBNetBuilder::compute(OptionsCont& oc, const std::set<std::string>& explicitTurnarounds, bool removeElements) { GeoConvHelper& geoConvHelper = GeoConvHelper::getProcessing(); const bool lefthand = oc.getBool("lefthand"); if (lefthand) { mirrorX(); }; // MODIFYING THE SETS OF NODES AND EDGES // Removes edges that are connecting the same node long before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Removing self-loops"); myNodeCont.removeSelfLoops(myDistrictCont, myEdgeCont, myTLLCont); PROGRESS_TIME_MESSAGE(before); // if (oc.exists("remove-edges.isolated") && oc.getBool("remove-edges.isolated")) { before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Finding isolated roads"); myNodeCont.removeIsolatedRoads(myDistrictCont, myEdgeCont, myTLLCont); PROGRESS_TIME_MESSAGE(before); } // if (oc.exists("keep-edges.postload") && oc.getBool("keep-edges.postload")) { if (oc.isSet("keep-edges.explicit") || oc.isSet("keep-edges.input-file")) { before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Removing unwished edges"); myEdgeCont.removeUnwishedEdges(myDistrictCont); PROGRESS_TIME_MESSAGE(before); } } if (oc.getBool("junctions.join") || (oc.exists("ramps.guess") && oc.getBool("ramps.guess"))) { // preliminary geometry computations to determine the length of edges // This depends on turning directions and sorting of edge list // in case junctions are joined geometry computations have to be repeated // preliminary roundabout computations to avoid damaging roundabouts via junctions.join or ramps.guess NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false); NBNodesEdgesSorter::sortNodesEdges(myNodeCont); myEdgeCont.computeLaneShapes(); myNodeCont.computeNodeShapes(); myEdgeCont.computeEdgeShapes(); if (oc.getBool("roundabouts.guess")) { myEdgeCont.guessRoundabouts(); } const std::set<EdgeSet>& roundabouts = myEdgeCont.getRoundabouts(); for (std::set<EdgeSet>::const_iterator it_round = roundabouts.begin(); it_round != roundabouts.end(); ++it_round) { std::vector<std::string> nodeIDs; for (EdgeSet::const_iterator it_edge = it_round->begin(); it_edge != it_round->end(); ++it_edge) { nodeIDs.push_back((*it_edge)->getToNode()->getID()); } myNodeCont.addJoinExclusion(nodeIDs); } } // join junctions (may create new "geometry"-nodes so it needs to come before removing these if (oc.exists("junctions.join-exclude") && oc.isSet("junctions.join-exclude")) { myNodeCont.addJoinExclusion(oc.getStringVector("junctions.join-exclude")); } unsigned int numJoined = myNodeCont.joinLoadedClusters(myDistrictCont, myEdgeCont, myTLLCont); if (oc.getBool("junctions.join")) { before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Joining junction clusters"); numJoined += myNodeCont.joinJunctions(oc.getFloat("junctions.join-dist"), myDistrictCont, myEdgeCont, myTLLCont); PROGRESS_TIME_MESSAGE(before); } if (oc.getBool("junctions.join") || (oc.exists("ramps.guess") && oc.getBool("ramps.guess"))) { // reset geometry to avoid influencing subsequent steps (ramps.guess) myEdgeCont.computeLaneShapes(); } if (numJoined > 0) { // bit of a misnomer since we're already done WRITE_MESSAGE(" Joined " + toString(numJoined) + " junction cluster(s)."); } // if (removeElements) { unsigned int no = 0; const bool removeGeometryNodes = oc.exists("geometry.remove") && oc.getBool("geometry.remove"); before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Removing empty nodes" + std::string(removeGeometryNodes ? " and geometry nodes" : "")); // removeUnwishedNodes needs turnDirections. @todo: try to call this less often NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false); no = myNodeCont.removeUnwishedNodes(myDistrictCont, myEdgeCont, myTLLCont, removeGeometryNodes); PROGRESS_TIME_MESSAGE(before); WRITE_MESSAGE(" " + toString(no) + " nodes removed."); } // MOVE TO ORIGIN // compute new boundary after network modifications have taken place Boundary boundary; for (std::map<std::string, NBNode*>::const_iterator it = myNodeCont.begin(); it != myNodeCont.end(); ++it) { boundary.add(it->second->getPosition()); } for (std::map<std::string, NBEdge*>::const_iterator it = myEdgeCont.begin(); it != myEdgeCont.end(); ++it) { boundary.add(it->second->getGeometry().getBoxBoundary()); } geoConvHelper.setConvBoundary(boundary); if (!oc.getBool("offset.disable-normalization") && oc.isDefault("offset.x") && oc.isDefault("offset.y")) { moveToOrigin(geoConvHelper, lefthand); } geoConvHelper.computeFinal(lefthand); // information needed for location element fixed at this point if (oc.exists("geometry.min-dist") && oc.isSet("geometry.min-dist")) { before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Reducing geometries"); myEdgeCont.reduceGeometries(oc.getFloat("geometry.min-dist")); PROGRESS_TIME_MESSAGE(before); } // @note: removing geometry can create similar edges so joinSimilarEdges must come afterwards // @note: likewise splitting can destroy similarities so joinSimilarEdges must come before if (removeElements && oc.getBool("edges.join")) { before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Joining similar edges"); myNodeCont.joinSimilarEdges(myDistrictCont, myEdgeCont, myTLLCont); PROGRESS_TIME_MESSAGE(before); } if (oc.getBool("opposites.guess")) { PROGRESS_BEGIN_MESSAGE("guessing opposite direction edges"); myEdgeCont.guessOpposites(); PROGRESS_DONE_MESSAGE(); } // if (oc.exists("geometry.split") && oc.getBool("geometry.split")) { before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Splitting geometry edges"); myEdgeCont.splitGeometry(myNodeCont); PROGRESS_TIME_MESSAGE(before); } // turning direction before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Computing turning directions"); NBTurningDirectionsComputer::computeTurnDirections(myNodeCont); PROGRESS_TIME_MESSAGE(before); // correct edge geometries to avoid overlap myNodeCont.avoidOverlap(); // guess ramps if ((oc.exists("ramps.guess") && oc.getBool("ramps.guess")) || (oc.exists("ramps.set") && oc.isSet("ramps.set"))) { before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Guessing and setting on-/off-ramps"); NBNodesEdgesSorter::sortNodesEdges(myNodeCont); NBRampsComputer::computeRamps(*this, oc); PROGRESS_TIME_MESSAGE(before); } // guess sidewalks if (oc.getBool("sidewalks.guess") || oc.getBool("sidewalks.guess.from-permissions")) { const int sidewalks = myEdgeCont.guessSidewalks(oc.getFloat("default.sidewalk-width"), oc.getFloat("sidewalks.guess.min-speed"), oc.getFloat("sidewalks.guess.max-speed"), oc.getBool("sidewalks.guess.from-permissions")); WRITE_MESSAGE("Guessed " + toString(sidewalks) + " sidewalks."); } // check whether any not previously setable connections may be set now myEdgeCont.recheckPostProcessConnections(); // remap ids if wished if (oc.getBool("numerical-ids")) { int numChangedEdges = myEdgeCont.mapToNumericalIDs(); int numChangedNodes = myNodeCont.mapToNumericalIDs(); if (numChangedEdges + numChangedNodes > 0) { WRITE_MESSAGE("Remapped " + toString(numChangedEdges) + " edge IDs and " + toString(numChangedNodes) + " node IDs."); } } // if (oc.exists("geometry.max-angle")) { myEdgeCont.checkGeometries( DEG2RAD(oc.getFloat("geometry.max-angle")), oc.getFloat("geometry.min-radius"), oc.getBool("geometry.min-radius.fix")); } // GEOMETRY COMPUTATION // before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Sorting nodes' edges"); NBNodesEdgesSorter::sortNodesEdges(myNodeCont); PROGRESS_TIME_MESSAGE(before); myEdgeCont.computeLaneShapes(); // before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Computing node shapes"); if (oc.exists("geometry.junction-mismatch-threshold")) { myNodeCont.computeNodeShapes(oc.getFloat("geometry.junction-mismatch-threshold")); } else { myNodeCont.computeNodeShapes(); } PROGRESS_TIME_MESSAGE(before); // before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Computing edge shapes"); myEdgeCont.computeEdgeShapes(); PROGRESS_TIME_MESSAGE(before); // resort edges based on the node and edge shapes NBNodesEdgesSorter::sortNodesEdges(myNodeCont, true); NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false); // APPLY SPEED MODIFICATIONS if (oc.exists("speed.offset")) { const SUMOReal speedOffset = oc.getFloat("speed.offset"); const SUMOReal speedFactor = oc.getFloat("speed.factor"); if (speedOffset != 0 || speedFactor != 1 || oc.isSet("speed.minimum")) { const SUMOReal speedMin = oc.isSet("speed.minimum") ? oc.getFloat("speed.minimum") : -std::numeric_limits<SUMOReal>::infinity(); before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Applying speed modifications"); for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) { (*i).second->setSpeed(-1, MAX2((*i).second->getSpeed() * speedFactor + speedOffset, speedMin)); } PROGRESS_TIME_MESSAGE(before); } } // CONNECTIONS COMPUTATION // before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Computing node types"); NBNodeTypeComputer::computeNodeTypes(myNodeCont); PROGRESS_TIME_MESSAGE(before); // bool haveCrossings = false; if (oc.getBool("crossings.guess")) { haveCrossings = true; int crossings = 0; for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) { crossings += (*i).second->guessCrossings(); } WRITE_MESSAGE("Guessed " + toString(crossings) + " pedestrian crossings."); } if (!haveCrossings) { // recheck whether we had crossings in the input for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) { if (i->second->getCrossings().size() > 0) { haveCrossings = true; break; } } } if (oc.isDefault("no-internal-links") && !haveCrossings && myHaveLoadedNetworkWithoutInternalEdges) { oc.set("no-internal-links", "true"); } // before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Computing priorities"); NBEdgePriorityComputer::computeEdgePriorities(myNodeCont); PROGRESS_TIME_MESSAGE(before); // before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Computing approached edges"); myEdgeCont.computeEdge2Edges(oc.getBool("no-left-connections")); PROGRESS_TIME_MESSAGE(before); // if (oc.getBool("roundabouts.guess")) { before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Guessing and setting roundabouts"); const int numGuessed = myEdgeCont.guessRoundabouts(); if (numGuessed > 0) { WRITE_MESSAGE(" Guessed " + toString(numGuessed) + " roundabout(s)."); } PROGRESS_TIME_MESSAGE(before); } myEdgeCont.markRoundabouts(); // before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Computing approaching lanes"); myEdgeCont.computeLanes2Edges(); PROGRESS_TIME_MESSAGE(before); // before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Dividing of lanes on approached lanes"); myNodeCont.computeLanes2Lanes(); myEdgeCont.sortOutgoingLanesConnections(); PROGRESS_TIME_MESSAGE(before); // before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Processing turnarounds"); if (!oc.getBool("no-turnarounds")) { myEdgeCont.appendTurnarounds(oc.getBool("no-turnarounds.tls")); } else { myEdgeCont.appendTurnarounds(explicitTurnarounds, oc.getBool("no-turnarounds.tls")); } PROGRESS_TIME_MESSAGE(before); // before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Rechecking of lane endings"); myEdgeCont.recheckLanes(); PROGRESS_TIME_MESSAGE(before); if (haveCrossings && !oc.getBool("no-internal-links")) { for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) { i->second->buildCrossingsAndWalkingAreas(); } } // GUESS TLS POSITIONS before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Assigning nodes to traffic lights"); if (oc.isSet("tls.set")) { std::vector<std::string> tlControlledNodes = oc.getStringVector("tls.set"); TrafficLightType type = SUMOXMLDefinitions::TrafficLightTypes.get(oc.getString("tls.default-type")); for (std::vector<std::string>::const_iterator i = tlControlledNodes.begin(); i != tlControlledNodes.end(); ++i) { NBNode* node = myNodeCont.retrieve(*i); if (node == 0) { WRITE_WARNING("Building a tl-logic for junction '" + *i + "' is not possible." + "\n The junction '" + *i + "' is not known."); } else { myNodeCont.setAsTLControlled(node, myTLLCont, type); } } } myNodeCont.guessTLs(oc, myTLLCont); PROGRESS_TIME_MESSAGE(before); // if (oc.getBool("tls.join")) { before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Joining traffic light nodes"); myNodeCont.joinTLS(myTLLCont, oc.getFloat("tls.join-dist")); PROGRESS_TIME_MESSAGE(before); } // COMPUTING RIGHT-OF-WAY AND TRAFFIC LIGHT PROGRAMS // before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Computing traffic light control information"); myTLLCont.setTLControllingInformation(myEdgeCont, myNodeCont); PROGRESS_TIME_MESSAGE(before); // before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Computing node logics"); myNodeCont.computeLogics(myEdgeCont, oc); PROGRESS_TIME_MESSAGE(before); // before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Computing traffic light logics"); std::pair<unsigned int, unsigned int> numbers = myTLLCont.computeLogics(oc); PROGRESS_TIME_MESSAGE(before); std::string progCount = ""; if (numbers.first != numbers.second) { progCount = "(" + toString(numbers.second) + " programs) "; } WRITE_MESSAGE(" " + toString(numbers.first) + " traffic light(s) " + progCount + "computed."); // if (oc.isSet("street-sign-output")) { before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Generating street signs"); myEdgeCont.generateStreetSigns(); PROGRESS_TIME_MESSAGE(before); } // FINISHING INNER EDGES if (!oc.getBool("no-internal-links")) { before = SysUtils::getCurrentMillis(); PROGRESS_BEGIN_MESSAGE("Building inner edges"); for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) { (*i).second->sortOutgoingConnectionsByIndex(); } // walking areas shall only be built if crossings are wished as well for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) { (*i).second->buildInnerEdges(); } PROGRESS_TIME_MESSAGE(before); } if (lefthand) { mirrorX(); }; // report WRITE_MESSAGE("-----------------------------------------------------"); WRITE_MESSAGE("Summary:"); myNodeCont.printBuiltNodesStatistics(); WRITE_MESSAGE(" Network boundaries:"); WRITE_MESSAGE(" Original boundary : " + toString(geoConvHelper.getOrigBoundary())); WRITE_MESSAGE(" Applied offset : " + toString(geoConvHelper.getOffsetBase())); WRITE_MESSAGE(" Converted boundary : " + toString(geoConvHelper.getConvBoundary())); WRITE_MESSAGE("-----------------------------------------------------"); NBRequest::reportWarnings(); // report on very large networks if (MAX2(geoConvHelper.getConvBoundary().xmax(), geoConvHelper.getConvBoundary().ymax()) > 1000000 || MIN2(geoConvHelper.getConvBoundary().xmin(), geoConvHelper.getConvBoundary().ymin()) < -1000000) { WRITE_WARNING("Network contains very large coordinates and will probably flicker in the GUI. Check for outlying nodes and make sure the network is shifted to the coordinate origin"); } }
/** * Computes the routes saving them */ void computeRoutes(RONet& net, ROLoader& loader, OptionsCont& oc) { // initialise the loader loader.openRoutes(net); // build the router auto ttFunction = gWeightsRandomFactor > 1 ? &ROEdge::getTravelTimeStaticRandomized : &ROEdge::getTravelTimeStatic; SUMOAbstractRouter<ROEdge, ROVehicle>* router; const std::string measure = oc.getString("weight-attribute"); const std::string routingAlgorithm = oc.getString("routing-algorithm"); const SUMOTime begin = string2time(oc.getString("begin")); const SUMOTime end = string2time(oc.getString("end")); if (measure == "traveltime") { if (routingAlgorithm == "dijkstra") { if (net.hasPermissions()) { router = new DijkstraRouter<ROEdge, ROVehicle, SUMOAbstractRouterPermissions<ROEdge, ROVehicle> >( ROEdge::getAllEdges(), oc.getBool("ignore-errors"), ttFunction); } else { router = new DijkstraRouter<ROEdge, ROVehicle, SUMOAbstractRouter<ROEdge, ROVehicle> >( ROEdge::getAllEdges(), oc.getBool("ignore-errors"), ttFunction); } } else if (routingAlgorithm == "astar") { if (net.hasPermissions()) { typedef AStarRouter<ROEdge, ROVehicle, SUMOAbstractRouterPermissions<ROEdge, ROVehicle> > AStar; std::shared_ptr<const AStar::LookupTable> lookup; if (oc.isSet("astar.all-distances")) { lookup = std::make_shared<const AStar::FLT>(oc.getString("astar.all-distances"), (int)ROEdge::getAllEdges().size()); } else if (oc.isSet("astar.landmark-distances")) { CHRouterWrapper<ROEdge, ROVehicle, SUMOAbstractRouterPermissions<ROEdge, ROVehicle> > router( ROEdge::getAllEdges(), true, &ROEdge::getTravelTimeStatic, begin, end, std::numeric_limits<int>::max(), 1); ROVehicle defaultVehicle(SUMOVehicleParameter(), nullptr, net.getVehicleTypeSecure(DEFAULT_VTYPE_ID), &net); lookup = std::make_shared<const AStar::LMLT>(oc.getString("astar.landmark-distances"), ROEdge::getAllEdges(), &router, &defaultVehicle, oc.isSet("astar.save-landmark-distances") ? oc.getString("astar.save-landmark-distances") : "", oc.getInt("routing-threads")); } router = new AStar(ROEdge::getAllEdges(), oc.getBool("ignore-errors"), ttFunction, lookup); } else { typedef AStarRouter<ROEdge, ROVehicle, SUMOAbstractRouter<ROEdge, ROVehicle> > AStar; std::shared_ptr<const AStar::LookupTable> lookup; if (oc.isSet("astar.all-distances")) { lookup = std::make_shared<const AStar::FLT>(oc.getString("astar.all-distances"), (int)ROEdge::getAllEdges().size()); } else if (oc.isSet("astar.landmark-distances")) { CHRouterWrapper<ROEdge, ROVehicle, SUMOAbstractRouter<ROEdge, ROVehicle> > router( ROEdge::getAllEdges(), true, &ROEdge::getTravelTimeStatic, begin, end, std::numeric_limits<int>::max(), 1); ROVehicle defaultVehicle(SUMOVehicleParameter(), nullptr, net.getVehicleTypeSecure(DEFAULT_VTYPE_ID), &net); lookup = std::make_shared<const AStar::LMLT>(oc.getString("astar.landmark-distances"), ROEdge::getAllEdges(), &router, &defaultVehicle, oc.isSet("astar.save-landmark-distances") ? oc.getString("astar.save-landmark-distances") : "", oc.getInt("routing-threads")); } router = new AStar(ROEdge::getAllEdges(), oc.getBool("ignore-errors"), ttFunction, lookup); } } else if (routingAlgorithm == "CH") { const SUMOTime weightPeriod = (oc.isSet("weight-files") ? string2time(oc.getString("weight-period")) : std::numeric_limits<int>::max()); if (net.hasPermissions()) { router = new CHRouter<ROEdge, ROVehicle, SUMOAbstractRouterPermissions<ROEdge, ROVehicle> >( ROEdge::getAllEdges(), oc.getBool("ignore-errors"), &ROEdge::getTravelTimeStatic, SVC_IGNORING, weightPeriod, true); } else { router = new CHRouter<ROEdge, ROVehicle, SUMOAbstractRouter<ROEdge, ROVehicle> >( ROEdge::getAllEdges(), oc.getBool("ignore-errors"), &ROEdge::getTravelTimeStatic, SVC_IGNORING, weightPeriod, false); } } else if (routingAlgorithm == "CHWrapper") { const SUMOTime weightPeriod = (oc.isSet("weight-files") ? string2time(oc.getString("weight-period")) : std::numeric_limits<int>::max()); router = new CHRouterWrapper<ROEdge, ROVehicle, SUMOAbstractRouterPermissions<ROEdge, ROVehicle> >( ROEdge::getAllEdges(), oc.getBool("ignore-errors"), &ROEdge::getTravelTimeStatic, begin, end, weightPeriod, oc.getInt("routing-threads")); } else { throw ProcessError("Unknown routing Algorithm '" + routingAlgorithm + "'!"); } } else { DijkstraRouter<ROEdge, ROVehicle, SUMOAbstractRouterPermissions<ROEdge, ROVehicle> >::Operation op; if (measure == "CO") { op = &ROEdge::getEmissionEffort<PollutantsInterface::CO>; } else if (measure == "CO2") { op = &ROEdge::getEmissionEffort<PollutantsInterface::CO2>; } else if (measure == "PMx") { op = &ROEdge::getEmissionEffort<PollutantsInterface::PM_X>; } else if (measure == "HC") { op = &ROEdge::getEmissionEffort<PollutantsInterface::HC>; } else if (measure == "NOx") { op = &ROEdge::getEmissionEffort<PollutantsInterface::NO_X>; } else if (measure == "fuel") { op = &ROEdge::getEmissionEffort<PollutantsInterface::FUEL>; } else if (measure == "electricity") { op = &ROEdge::getEmissionEffort<PollutantsInterface::ELEC>; } else if (measure == "noise") { op = &ROEdge::getNoiseEffort; } else { throw ProcessError("Unknown measure (weight attribute '" + measure + "')!"); } if (net.hasPermissions()) { router = new DijkstraRouter<ROEdge, ROVehicle, SUMOAbstractRouterPermissions<ROEdge, ROVehicle> >( ROEdge::getAllEdges(), oc.getBool("ignore-errors"), op, ttFunction); } else { router = new DijkstraRouter<ROEdge, ROVehicle, SUMOAbstractRouter<ROEdge, ROVehicle> >( ROEdge::getAllEdges(), oc.getBool("ignore-errors"), op, ttFunction); } } int carWalk = 0; for (const std::string& opt : oc.getStringVector("persontrip.transfer.car-walk")) { if (opt == "parkingAreas") { carWalk |= ROIntermodalRouter::Network::PARKING_AREAS; } else if (opt == "ptStops") { carWalk |= ROIntermodalRouter::Network::PT_STOPS; } else if (opt == "allJunctions") { carWalk |= ROIntermodalRouter::Network::ALL_JUNCTIONS; } } RORouterProvider provider(router, new PedestrianRouter<ROEdge, ROLane, RONode, ROVehicle>(), new ROIntermodalRouter(RONet::adaptIntermodalRouter, carWalk, routingAlgorithm)); // process route definitions try { net.openOutput(oc); loader.processRoutes(begin, end, string2time(oc.getString("route-steps")), net, provider); net.writeIntermodal(oc, provider.getIntermodalRouter()); // end the processing net.cleanup(); } catch (ProcessError&) { net.cleanup(); throw; } }
void NIImporter_SUMO::_loadNetwork(OptionsCont& oc) { // check whether the option is set (properly) if (!oc.isUsableFileList("sumo-net-file")) { return; } // parse file(s) std::vector<std::string> files = oc.getStringVector("sumo-net-file"); for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) { if (!FileHelpers::isReadable(*file)) { WRITE_ERROR("Could not open sumo-net-file '" + *file + "'."); return; } setFileName(*file); PROGRESS_BEGIN_MESSAGE("Parsing sumo-net from '" + *file + "'"); XMLSubSys::runParser(*this, *file, true); PROGRESS_DONE_MESSAGE(); } // build edges for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) { EdgeAttrs* ed = (*i).second; // skip internal edges if (ed->func == EDGEFUNC_INTERNAL || ed->func == EDGEFUNC_CROSSING || ed->func == EDGEFUNC_WALKINGAREA) { continue; } // get and check the nodes NBNode* from = myNodeCont.retrieve(ed->fromNode); NBNode* to = myNodeCont.retrieve(ed->toNode); if (from == 0) { WRITE_ERROR("Edge's '" + ed->id + "' from-node '" + ed->fromNode + "' is not known."); continue; } if (to == 0) { WRITE_ERROR("Edge's '" + ed->id + "' to-node '" + ed->toNode + "' is not known."); continue; } // edge shape PositionVector geom; if (ed->shape.size() > 0) { geom = ed->shape; } else { // either the edge has default shape consisting only of the two node // positions or we have a legacy network geom = reconstructEdgeShape(ed, from->getPosition(), to->getPosition()); } // build and insert the edge NBEdge* e = new NBEdge(ed->id, from, to, ed->type, ed->maxSpeed, (unsigned int) ed->lanes.size(), ed->priority, NBEdge::UNSPECIFIED_WIDTH, NBEdge::UNSPECIFIED_OFFSET, geom, ed->streetName, "", ed->lsf, true); // always use tryIgnoreNodePositions to keep original shape e->setLoadedLength(ed->length); if (!myNetBuilder.getEdgeCont().insert(e)) { WRITE_ERROR("Could not insert edge '" + ed->id + "'."); delete e; continue; } ed->builtEdge = myNetBuilder.getEdgeCont().retrieve(ed->id); } // assign further lane attributes (edges are built) for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) { EdgeAttrs* ed = (*i).second; NBEdge* nbe = ed->builtEdge; if (nbe == 0) { // inner edge or removed by explicit list, vclass, ... continue; } for (unsigned int fromLaneIndex = 0; fromLaneIndex < (unsigned int) ed->lanes.size(); ++fromLaneIndex) { LaneAttrs* lane = ed->lanes[fromLaneIndex]; // connections const std::vector<Connection>& connections = lane->connections; for (std::vector<Connection>::const_iterator c_it = connections.begin(); c_it != connections.end(); c_it++) { const Connection& c = *c_it; if (myEdges.count(c.toEdgeID) == 0) { WRITE_ERROR("Unknown edge '" + c.toEdgeID + "' given in connection."); continue; } NBEdge* toEdge = myEdges[c.toEdgeID]->builtEdge; if (toEdge == 0) { // removed by explicit list, vclass, ... continue; } if (nbe->hasConnectionTo(toEdge, c.toLaneIdx)) { WRITE_WARNING("Target lane '" + toEdge->getLaneID(c.toLaneIdx) + "' has multiple connections from '" + nbe->getID() + "'."); } nbe->addLane2LaneConnection( fromLaneIndex, toEdge, c.toLaneIdx, NBEdge::L2L_VALIDATED, true, c.mayDefinitelyPass, c.keepClear, c.contPos); // maybe we have a tls-controlled connection if (c.tlID != "" && myRailSignals.count(c.tlID) == 0) { const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(c.tlID); if (programs.size() > 0) { std::map<std::string, NBTrafficLightDefinition*>::const_iterator it; for (it = programs.begin(); it != programs.end(); it++) { NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second); if (tlDef) { tlDef->addConnection(nbe, toEdge, fromLaneIndex, c.toLaneIdx, c.tlLinkNo); } else { throw ProcessError("Corrupt traffic light definition '" + c.tlID + "' (program '" + it->first + "')"); } } } else { WRITE_ERROR("The traffic light '" + c.tlID + "' is not known."); } } } // allow/disallow XXX preferred nbe->setPermissions(parseVehicleClasses(lane->allow, lane->disallow), fromLaneIndex); // width, offset nbe->setLaneWidth(fromLaneIndex, lane->width); nbe->setEndOffset(fromLaneIndex, lane->endOffset); nbe->setSpeed(fromLaneIndex, lane->maxSpeed); } nbe->declareConnectionsAsLoaded(); if (!nbe->hasLaneSpecificWidth() && nbe->getLanes()[0].width != NBEdge::UNSPECIFIED_WIDTH) { nbe->setLaneWidth(-1, nbe->getLaneWidth(0)); } if (!nbe->hasLaneSpecificEndOffset() && nbe->getEndOffset(0) != NBEdge::UNSPECIFIED_OFFSET) { nbe->setEndOffset(-1, nbe->getEndOffset(0)); } } // insert loaded prohibitions for (std::vector<Prohibition>::const_iterator it = myProhibitions.begin(); it != myProhibitions.end(); it++) { NBEdge* prohibitedFrom = myEdges[it->prohibitedFrom]->builtEdge; NBEdge* prohibitedTo = myEdges[it->prohibitedTo]->builtEdge; NBEdge* prohibitorFrom = myEdges[it->prohibitorFrom]->builtEdge; NBEdge* prohibitorTo = myEdges[it->prohibitorTo]->builtEdge; if (prohibitedFrom == 0) { WRITE_WARNING("Edge '" + it->prohibitedFrom + "' in prohibition was not built"); } else if (prohibitedTo == 0) { WRITE_WARNING("Edge '" + it->prohibitedTo + "' in prohibition was not built"); } else if (prohibitorFrom == 0) { WRITE_WARNING("Edge '" + it->prohibitorFrom + "' in prohibition was not built"); } else if (prohibitorTo == 0) { WRITE_WARNING("Edge '" + it->prohibitorTo + "' in prohibition was not built"); } else { NBNode* n = prohibitedFrom->getToNode(); n->addSortedLinkFoes( NBConnection(prohibitorFrom, prohibitorTo), NBConnection(prohibitedFrom, prohibitedTo)); } } if (!myHaveSeenInternalEdge) { myNetBuilder.haveLoadedNetworkWithoutInternalEdges(); } if (oc.isDefault("lefthand")) { oc.set("lefthand", toString(myAmLefthand)); } if (oc.isDefault("junctions.corner-detail")) { oc.set("junctions.corner-detail", toString(myCornerDetail)); } if (oc.isDefault("junctions.internal-link-detail") && myLinkDetail > 0) { oc.set("junctions.internal-link-detail", toString(myLinkDetail)); } if (!deprecatedVehicleClassesSeen.empty()) { WRITE_WARNING("Deprecated vehicle class(es) '" + toString(deprecatedVehicleClassesSeen) + "' in input network."); deprecatedVehicleClassesSeen.clear(); } // add loaded crossings if (!oc.getBool("no-internal-links")) { for (std::map<std::string, std::vector<Crossing> >::const_iterator it = myPedestrianCrossings.begin(); it != myPedestrianCrossings.end(); ++it) { NBNode* node = myNodeCont.retrieve((*it).first); for (std::vector<Crossing>::const_iterator it_c = (*it).second.begin(); it_c != (*it).second.end(); ++it_c) { const Crossing& crossing = (*it_c); EdgeVector edges; for (std::vector<std::string>::const_iterator it_e = crossing.crossingEdges.begin(); it_e != crossing.crossingEdges.end(); ++it_e) { NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(*it_e); // edge might have been removed due to options if (edge != 0) { edges.push_back(edge); } } if (edges.size() > 0) { node->addCrossing(edges, crossing.width, crossing.priority, true); } } } } // add roundabouts for (std::vector<std::vector<std::string> >::const_iterator it = myRoundabouts.begin(); it != myRoundabouts.end(); ++it) { EdgeSet roundabout; for (std::vector<std::string>::const_iterator it_r = it->begin(); it_r != it->end(); ++it_r) { NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(*it_r); if (edge == 0) { if (!myNetBuilder.getEdgeCont().wasIgnored(*it_r)) { WRITE_ERROR("Unknown edge '" + (*it_r) + "' in roundabout"); } } else { roundabout.insert(edge); } } myNetBuilder.getEdgeCont().addRoundabout(roundabout); } }
// =========================================================================== // method definitions // =========================================================================== // --------------------------------------------------------------------------- // static methods (interface in this case) // --------------------------------------------------------------------------- void NIImporter_OpenDrive::loadNetwork(const OptionsCont &oc, NBNetBuilder &nb) { // check whether the option is set (properly) if (!oc.isUsableFileList("opendrive")) { return; } // build the handler std::vector<OpenDriveEdge> innerEdges, outerEdges; NIImporter_OpenDrive handler(nb.getNodeCont(), innerEdges, outerEdges); // parse file(s) std::vector<std::string> files = oc.getStringVector("opendrive"); for (std::vector<std::string>::const_iterator file=files.begin(); file!=files.end(); ++file) { if (!FileHelpers::exists(*file)) { MsgHandler::getErrorInstance()->inform("Could not open opendrive file '" + *file + "'."); return; } handler.setFileName(*file); MsgHandler::getMessageInstance()->beginProcessMsg("Parsing opendrive from '" + *file + "'..."); XMLSubSys::runParser(handler, *file); MsgHandler::getMessageInstance()->endProcessMsg("done."); } // convert geometries into a discretised representation computeShapes(innerEdges); computeShapes(outerEdges); // ------------------------- // node building // ------------------------- // build nodes#1 // look at all links which belong to a node, collect their bounding boxes // and place the node in the middle of this bounding box std::map<std::string, Boundary> posMap; std::map<std::string, std::string> edge2junction; // compute node positions for (std::vector<OpenDriveEdge>::iterator i=innerEdges.begin(); i!=innerEdges.end(); ++i) { OpenDriveEdge &e = *i; assert(e.junction!="-1" && e.junction!=""); edge2junction[e.id] = e.junction; if (posMap.find(e.junction)==posMap.end()) { posMap[e.junction] = Boundary(); } posMap[e.junction].add(e.geom.getBoxBoundary()); } // build nodes for (std::map<std::string, Boundary>::iterator i=posMap.begin(); i!=posMap.end(); ++i) { if (!nb.getNodeCont().insert((*i).first, (*i).second.getCenter())) { throw ProcessError("Could not add node '" + (*i).first + "'."); } } // assign built nodes for (std::vector<OpenDriveEdge>::iterator i=outerEdges.begin(); i!=outerEdges.end(); ++i) { OpenDriveEdge &e = *i; for (std::vector<OpenDriveLink>::iterator j=e.links.begin(); j!=e.links.end(); ++j) { OpenDriveLink &l = *j; if (l.elementType!=OPENDRIVE_ET_ROAD) { // set node information setNodeSecure(nb.getNodeCont(), e, l.elementID, l.linkType); continue; } if (edge2junction.find(l.elementID)!=edge2junction.end()) { // set node information of an internal road setNodeSecure(nb.getNodeCont(), e, edge2junction[l.elementID], l.linkType); continue; } } } // we should now have all nodes set for links which are not outer edge-to-outer edge links // build nodes#2 // build nodes for all outer edge-to-outer edge connections for (std::vector<OpenDriveEdge>::iterator i=outerEdges.begin(); i!=outerEdges.end(); ++i) { OpenDriveEdge &e = *i; for (std::vector<OpenDriveLink>::iterator j=e.links.begin(); j!=e.links.end(); ++j) { OpenDriveLink &l = *j; if (l.elementType!=OPENDRIVE_ET_ROAD || edge2junction.find(l.elementID)!=edge2junction.end()) { // is a connection to an internal edge, or a node, skip continue; } // we have a direct connection between to external edges std::string id1 = e.id; std::string id2 = l.elementID; if (id1<id2) { std::swap(id1, id2); } std::string nid = id1+"."+id2; if (nb.getNodeCont().retrieve(nid)==0) { // not yet seen, build Position2D pos = l.linkType==OPENDRIVE_LT_SUCCESSOR ? e.geom[(int)e.geom.size()-1] : e.geom[0]; if (!nb.getNodeCont().insert(nid, pos)) { throw ProcessError("Could not build node '" + nid + "'."); } } /* debug-stuff else { Position2D pos = l.linkType==OPENDRIVE_LT_SUCCESSOR ? e.geom[e.geom.size()-1] : e.geom[0]; cout << nid << " " << pos << " " << nb.getNodeCont().retrieve(nid)->getPosition() << endl; } */ setNodeSecure(nb.getNodeCont(), e, nid, l.linkType); } } // we should now have start/end nodes for all outer edge-to-outer edge connections // build nodes#3 // assign further nodes generated from inner-edges // these nodes have not been assigned earlier, because the connectiosn are referenced in inner-edges for (std::vector<OpenDriveEdge>::iterator i=outerEdges.begin(); i!=outerEdges.end(); ++i) { OpenDriveEdge &e = *i; if (e.to!=0&&e.from!=0) { continue; } for (std::vector<OpenDriveEdge>::iterator j=innerEdges.begin(); j!=innerEdges.end(); ++j) { OpenDriveEdge &ie = *j; for (std::vector<OpenDriveLink>::iterator k=ie.links.begin(); k!=ie.links.end(); ++k) { OpenDriveLink &il = *k; if (il.elementType!=OPENDRIVE_ET_ROAD || il.elementID!=e.id) { // not conneted to the currently investigated outer edge continue; } std::string nid = edge2junction[ie.id]; if (il.contactPoint==OPENDRIVE_CP_START) { setNodeSecure(nb.getNodeCont(), e, nid, OPENDRIVE_LT_PREDECESSOR); } else { setNodeSecure(nb.getNodeCont(), e, nid, OPENDRIVE_LT_SUCCESSOR); } } } } // // build start/end nodes which were not defined previously for (std::vector<OpenDriveEdge>::iterator i=outerEdges.begin(); i!=outerEdges.end(); ++i) { OpenDriveEdge &e = *i; if (e.from==0) { std::string nid = e.id + ".begin"; Position2D pos(e.geometries[0].x, e.geometries[0].y); e.from = getOrBuildNode(nid, e.geom[0], nb.getNodeCont()); } if (e.to==0) { std::string nid = e.id + ".end"; Position2D pos(e.geometries[e.geometries.size()-1].x, e.geometries[e.geometries.size()-1].y); e.to = getOrBuildNode(nid, e.geom[(int)e.geom.size()-1], nb.getNodeCont()); } } // ------------------------- // edge building // ------------------------- std::map<NBEdge*, std::map<int, int> > fromLaneMap; std::map<NBEdge*, std::map<int, int> > toLaneMap; // build edges for (std::vector<OpenDriveEdge>::iterator i=outerEdges.begin(); i!=outerEdges.end(); ++i) { OpenDriveEdge &e = *i; SUMOReal speed = nb.getTypeCont().getDefaultSpeed(); int priority = nb.getTypeCont().getDefaultPriority(); unsigned int nolanes = e.getMaxLaneNumber(SUMO_TAG_OPENDRIVE_RIGHT); if (nolanes>0) { NBEdge *nbe = new NBEdge("-" + e.id, e.from, e.to, "", speed, nolanes, priority, e.geom, NBEdge::LANESPREAD_RIGHT, true); if (!nb.getEdgeCont().insert(nbe)) { throw ProcessError("Could not add edge '" + std::string("-") + e.id + "'."); } fromLaneMap[nbe] = e.laneSections.back().buildLaneMapping(SUMO_TAG_OPENDRIVE_RIGHT); toLaneMap[nbe] = e.laneSections[0].buildLaneMapping(SUMO_TAG_OPENDRIVE_RIGHT); } nolanes = e.getMaxLaneNumber(SUMO_TAG_OPENDRIVE_LEFT); if (nolanes>0) { NBEdge *nbe = new NBEdge(e.id, e.to, e.from, "", speed, nolanes, priority, e.geom.reverse(), NBEdge::LANESPREAD_RIGHT, true); if (!nb.getEdgeCont().insert(nbe)) { throw ProcessError("Could not add edge '" + e.id + "'."); } fromLaneMap[nbe] = e.laneSections[0].buildLaneMapping(SUMO_TAG_OPENDRIVE_LEFT); toLaneMap[nbe] = e.laneSections.back().buildLaneMapping(SUMO_TAG_OPENDRIVE_LEFT); } } // ------------------------- // connections building // ------------------------- std::vector<Connection> connections; // connections#1 // build connections between outer-edges for (std::vector<OpenDriveEdge>::iterator i=outerEdges.begin(); i!=outerEdges.end(); ++i) { OpenDriveEdge &e = *i; for (std::vector<OpenDriveLink>::iterator j=e.links.begin(); j!=e.links.end(); ++j) { OpenDriveLink &l = *j; if (l.elementType!=OPENDRIVE_ET_ROAD) { // we are not interested in connections to nodes continue; } if (edge2junction.find(l.elementID)!=edge2junction.end()) { // connection via an inner-road addViaConnectionSecure(nb.getEdgeCont(), nb.getNodeCont().retrieve(edge2junction[l.elementID]), e, l.linkType, l.elementID, connections); } else { // connection between two outer-edges; can be used directly std::vector<OpenDriveEdge>::iterator p = std::find_if(outerEdges.begin(), outerEdges.end(), edge_by_id_finder(l.elementID)); if (p==outerEdges.end()) { throw ProcessError("Could not find connection edge."); } std::string id1 = e.id; std::string id2 = (*p).id; if (id1<id2) { std::swap(id1, id2); } std::string nid = id1+"."+id2; if (l.linkType==OPENDRIVE_LT_PREDECESSOR) { addE2EConnectionsSecure(nb.getEdgeCont(), nb.getNodeCont().retrieve(nid), *p, e, connections); } else { addE2EConnectionsSecure(nb.getEdgeCont(), nb.getNodeCont().retrieve(nid), e, *p, connections); } } } } /* for (std::vector<OpenDriveEdge>::iterator i=innerEdges.begin(); i!=innerEdges.end(); ++i) { OpenDriveEdge &e = *i; std::string pred, succ; ContactPoint predC, succC; for (std::vector<OpenDriveLink>::iterator j=e.links.begin(); j!=e.links.end(); ++j) { OpenDriveLink &l = *j; if (l.elementType!=OPENDRIVE_ET_ROAD) { // we are not interested in connections to nodes cout << "unsupported" << endl; continue; } if(edge2junction.find(l.elementID)!=edge2junction.end()) { // not supported cout << "unsupported" << endl; continue; } if(l.linkType==OPENDRIVE_LT_SUCCESSOR) { if(succ!="") { cout << "double succ" << endl; } succ = l.elementID; succC = l.contactPoint; } else { if(pred!="") { cout << "double pred" << endl; } pred = l.elementID; predC = l.contactPoint; } } if(e.getMaxLaneNumber(SUMO_TAG_OPENDRIVE_LEFT)!=0&&e.getMaxLaneNumber(SUMO_TAG_OPENDRIVE_RIGHT)!=0) { cout << "Both dirs given!" << endl; } bool isReversed = false; if(e.getMaxLaneNumber(SUMO_TAG_OPENDRIVE_LEFT)!=0) { // std::swap(pred, succ); //std::swap(predC, succC); isReversed = true; } if(succ==""||pred=="") { cout << "Missing edge." << endl; continue; // yes, occurs } NBNode *n = nb.getNodeCont().retrieve(edge2junction[e.id]); std::vector<OpenDriveEdge>::iterator predEdge = std::find_if(outerEdges.begin(), outerEdges.end(), edge_by_id_finder(pred)); if(predEdge==outerEdges.end()) { throw ProcessError("Could not find connection edge."); } std::vector<OpenDriveEdge>::iterator succEdge = std::find_if(outerEdges.begin(), outerEdges.end(), edge_by_id_finder(succ)); if(succEdge==outerEdges.end()) { throw ProcessError("Could not find connection edge."); } NBEdge *fromEdge, *toEdge; if(!isReversed) { fromEdge = predC==OPENDRIVE_CP_END ? nb.getEdgeCont().retrieve("-" + pred) : nb.getEdgeCont().retrieve(pred); toEdge = succC==OPENDRIVE_CP_START ? nb.getEdgeCont().retrieve("-" + succ) : nb.getEdgeCont().retrieve(succ); } else { fromEdge = predC!=OPENDRIVE_CP_END ? nb.getEdgeCont().retrieve("-" + pred) : nb.getEdgeCont().retrieve(pred); toEdge = succC!=OPENDRIVE_CP_START ? nb.getEdgeCont().retrieve("-" + succ) : nb.getEdgeCont().retrieve(succ); } /* Connection c( n->hasIncoming(nb.getEdgeCont().retrieve("-" + pred)) ? nb.getEdgeCont().retrieve("-" + pred) : nb.getEdgeCont().retrieve(pred), e.id, n->hasOutgoing(nb.getEdgeCont().retrieve("-" + succ)) ? nb.getEdgeCont().retrieve("-" + succ) : nb.getEdgeCont().retrieve(succ)); / Connection c(fromEdge, e.id, toEdge); if(c.from==0||c.to==0||c.from==c.to) { throw ProcessError("Something's false"); } setLaneConnections(c, *predEdge, c.from->getID()[0]!='-', c.from->getID()[0]=='-' ? SUMO_TAG_OPENDRIVE_RIGHT : SUMO_TAG_OPENDRIVE_LEFT, e, isReversed, !isReversed ? SUMO_TAG_OPENDRIVE_RIGHT : SUMO_TAG_OPENDRIVE_LEFT, *succEdge, c.to->getID()[0]!='-', c.to->getID()[0]=='-' ? SUMO_TAG_OPENDRIVE_RIGHT : SUMO_TAG_OPENDRIVE_LEFT); connections.push_back(c); } */ for (std::vector<Connection>::const_iterator i=connections.begin(); i!=connections.end(); ++i) { if ((*i).from==0 || (*i).to==0) { std::cout << "Nope." << std::endl; continue; } (*i).from->addEdge2EdgeConnection((*i).to); std::map<int, int> fromMap = fromLaneMap[(*i).from]; std::map<int, int> toMap = fromLaneMap[(*i).to]; for (std::vector<std::pair<int, int> >::const_iterator j=(*i).lanes.begin(); j!=(*i).lanes.end(); ++j) { int fromLane = fromMap[(*j).first]; int toLane = toMap[(*j).second]; if (static_cast<unsigned int>(fromLane)>=(*i).from->getNoLanes()||fromLane<0) { std::cout << "False " << std::endl; } if (static_cast<unsigned int>(toLane)>=(*i).to->getNoLanes()||toLane<0) { std::cout << "False " << std::endl; } (*i).from->addLane2LaneConnection(fromLane, (*i).to, toLane, NBEdge::L2L_VALIDATED, true); } } }
void NIImporter_SUMO::_loadNetwork(const OptionsCont& oc) { // check whether the option is set (properly) if (!oc.isUsableFileList("sumo-net-file")) { return; } // parse file(s) std::vector<std::string> files = oc.getStringVector("sumo-net-file"); for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) { if (!FileHelpers::exists(*file)) { WRITE_ERROR("Could not open sumo-net-file '" + *file + "'."); return; } setFileName(*file); PROGRESS_BEGIN_MESSAGE("Parsing sumo-net from '" + *file + "'"); XMLSubSys::runParser(*this, *file); PROGRESS_DONE_MESSAGE(); } // build edges for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) { EdgeAttrs* ed = (*i).second; // skip internal edges if (ed->func == toString(EDGEFUNC_INTERNAL)) { continue; } // get and check the nodes NBNode* from = myNodeCont.retrieve(ed->fromNode); NBNode* to = myNodeCont.retrieve(ed->toNode); if (from == 0) { WRITE_ERROR("Edge's '" + ed->id + "' from-node '" + ed->fromNode + "' is not known."); continue; } if (to == 0) { WRITE_ERROR("Edge's '" + ed->id + "' to-node '" + ed->toNode + "' is not known."); continue; } // edge shape PositionVector geom; if (ed->shape.size() > 0) { geom = ed->shape; mySuspectKeepShape = false; // no problem with reconstruction if edge shape is given explicit } else { // either the edge has default shape consisting only of the two node // positions or we have a legacy network geom = reconstructEdgeShape(ed, from->getPosition(), to->getPosition()); } // build and insert the edge NBEdge* e = new NBEdge(ed->id, from, to, ed->type, ed->maxSpeed, (unsigned int) ed->lanes.size(), ed->priority, NBEdge::UNSPECIFIED_WIDTH, NBEdge::UNSPECIFIED_OFFSET, geom, ed->streetName, ed->lsf, true); // always use tryIgnoreNodePositions to keep original shape e->setLoadedLength(ed->length); if (!myNetBuilder.getEdgeCont().insert(e)) { WRITE_ERROR("Could not insert edge '" + ed->id + "'."); delete e; continue; } ed->builtEdge = myNetBuilder.getEdgeCont().retrieve(ed->id); } // assign further lane attributes (edges are built) for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) { EdgeAttrs* ed = (*i).second; NBEdge* nbe = ed->builtEdge; if (nbe == 0) { // inner edge or removed by explicit list, vclass, ... continue; } for (unsigned int fromLaneIndex = 0; fromLaneIndex < (unsigned int) ed->lanes.size(); ++fromLaneIndex) { LaneAttrs* lane = ed->lanes[fromLaneIndex]; // connections const std::vector<Connection> &connections = lane->connections; for (std::vector<Connection>::const_iterator c_it = connections.begin(); c_it != connections.end(); c_it++) { const Connection& c = *c_it; if (myEdges.count(c.toEdgeID) == 0) { WRITE_ERROR("Unknown edge '" + c.toEdgeID + "' given in connection."); continue; } NBEdge* toEdge = myEdges[c.toEdgeID]->builtEdge; if (toEdge == 0) { // removed by explicit list, vclass, ... continue; } nbe->addLane2LaneConnection( fromLaneIndex, toEdge, c.toLaneIdx, NBEdge::L2L_VALIDATED, false, c.mayDefinitelyPass); // maybe we have a tls-controlled connection if (c.tlID != "") { const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(c.tlID); if (programs.size() > 0) { std::map<std::string, NBTrafficLightDefinition*>::const_iterator it; for (it = programs.begin(); it != programs.end(); it++) { NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second); if (tlDef) { tlDef->addConnection(nbe, toEdge, fromLaneIndex, c.toLaneIdx, c.tlLinkNo); } else { throw ProcessError("Corrupt traffic light definition '" + c.tlID + "' (program '" + it->first + "')"); } } } else { WRITE_ERROR("The traffic light '" + c.tlID + "' is not known."); } } } // allow/disallow SUMOVehicleClasses allowed; SUMOVehicleClasses disallowed; parseVehicleClasses(lane->allow, lane->disallow, allowed, disallowed); nbe->setVehicleClasses(allowed, disallowed, fromLaneIndex); // width, offset nbe->setWidth(fromLaneIndex, lane->width); nbe->setOffset(fromLaneIndex, lane->offset); nbe->setSpeed(fromLaneIndex, lane->maxSpeed); } nbe->declareConnectionsAsLoaded(); } // insert loaded prohibitions for (std::vector<Prohibition>::const_iterator it = myProhibitions.begin(); it != myProhibitions.end(); it++) { NBEdge* prohibitedFrom = myEdges[it->prohibitedFrom]->builtEdge; if (prohibitedFrom == 0) { WRITE_ERROR("Edge '" + it->prohibitedFrom + "' in prohibition was not built"); } else { NBNode* n = prohibitedFrom->getToNode(); n->addSortedLinkFoes( NBConnection(myEdges[it->prohibitorFrom]->builtEdge, myEdges[it->prohibitorTo]->builtEdge), NBConnection(prohibitedFrom, myEdges[it->prohibitedTo]->builtEdge)); } } // final warning if (mySuspectKeepShape) { WRITE_WARNING("The input network may have been built using option 'xml.keep-shape'.\n... Accuracy of junction positions cannot be guaranteed."); } }
// =========================================================================== // method definitions // =========================================================================== // --------------------------------------------------------------------------- // static methods (interface in this case) // --------------------------------------------------------------------------- void NIImporter_SUMO::loadNetwork(const OptionsCont &oc, NBNetBuilder &nb) { // check whether the option is set (properly) if (!oc.isUsableFileList("sumo-net")) { return; } // build the handler NIImporter_SUMO handler(nb.getNodeCont()); // parse file(s) std::vector<std::string> files = oc.getStringVector("sumo-net"); for (std::vector<std::string>::const_iterator file=files.begin(); file!=files.end(); ++file) { if (!FileHelpers::exists(*file)) { MsgHandler::getErrorInstance()->inform("Could not open sumo-net-file '" + *file + "'."); return; } handler.setFileName(*file); MsgHandler::getMessageInstance()->beginProcessMsg("Parsing sumo-net from '" + *file + "'..."); XMLSubSys::runParser(handler, *file); MsgHandler::getMessageInstance()->endProcessMsg("done."); } // build edges std::map<std::string, EdgeAttrs*> &loadedEdges = handler.myEdges; NBNodeCont &nodesCont = nb.getNodeCont(); NBEdgeCont &edgesCont = nb.getEdgeCont(); for (std::map<std::string, EdgeAttrs*>::const_iterator i=loadedEdges.begin(); i!=loadedEdges.end(); ++i) { EdgeAttrs *ed = (*i).second; // get and check the nodes NBNode *from = nodesCont.retrieve(ed->fromNode); NBNode *to = nodesCont.retrieve(ed->toNode); if (from==0) { MsgHandler::getErrorInstance()->inform("Edge's '" + ed->id + "' from-node '" + ed->fromNode + "' is not known."); continue; } if (to==0) { MsgHandler::getErrorInstance()->inform("Edge's '" + ed->id + "' to-node '" + ed->toNode + "' is not known."); continue; } // build and insert the edge NBEdge *e = new NBEdge(ed->id, from, to, ed->type, ed->maxSpeed, (unsigned int) ed->lanes.size(), ed->priority); if (!edgesCont.insert(e)) { MsgHandler::getErrorInstance()->inform("Could not insert edge '" + ed->id + "'."); delete e; continue; } ed->builtEdge = edgesCont.retrieve(ed->id); } // assign lane attributes (edges are built) for (std::map<std::string, EdgeAttrs*>::const_iterator i=loadedEdges.begin(); i!=loadedEdges.end(); ++i) { EdgeAttrs *ed = (*i).second; if (ed->builtEdge==0) { // earlier errors continue; } for (unsigned int j=0; j<(unsigned int) ed->lanes.size(); ++j) { const std::vector<EdgeLane> &connections = ed->lanes[j]->connections; for (std::vector<EdgeLane>::const_iterator k=connections.begin(); k!=connections.end(); ++k) { if ((*k).lane!="SUMO_NO_DESTINATION") { std::string lane = (*k).lane; std::string edge = lane.substr(0, lane.find('_')); int index = TplConvert<char>::_2int(lane.substr(lane.find('_')+1).c_str()); if (loadedEdges.find(edge)==loadedEdges.end()) { MsgHandler::getErrorInstance()->inform("Unknown edge given in succlane (for lane '" + lane + "')."); continue; } NBEdge *ce = loadedEdges.find(edge)->second->builtEdge; if (ce==0) { // earlier error or edge removal continue; } ed->builtEdge->addLane2LaneConnection(j, ce, index, NBEdge::L2L_VALIDATED); } } } } // clean up for (std::map<std::string, EdgeAttrs*>::const_iterator i=loadedEdges.begin(); i!=loadedEdges.end(); ++i) { EdgeAttrs *ed = (*i).second; for (std::vector<LaneAttrs*>::const_iterator j=ed->lanes.begin(); j!=ed->lanes.end(); ++j) { delete *j; } delete ed; } }