// searches for a specific edge EdgeIterator FindSmallestEdge(const NodeIterator from, const NodeIterator to) const { EdgeIterator smallest_edge = SPECIAL_EDGEID; EdgeWeight smallest_weight = INVALID_EDGE_WEIGHT; for (auto edge : GetAdjacentEdgeRange(from)) { const NodeID target = GetTarget(edge); const EdgeWeight weight = GetEdgeData(edge).distance; if (target == to && weight < smallest_weight) { smallest_edge = edge; smallest_weight = weight; } } return smallest_edge; }
EdgeIterator FindSmallestEdge(const NodeIterator from, const NodeIterator to, FilterFunction &&filter) const { static_assert(traits::HasDataMember<EdgeArrayEntry>::value, "Filtering on .data not possible without .data member attribute"); EdgeIterator smallest_edge = SPECIAL_EDGEID; EdgeWeight smallest_weight = INVALID_EDGE_WEIGHT; for (auto edge : GetAdjacentEdgeRange(from)) { const NodeID target = GetTarget(edge); const auto &data = GetEdgeData(edge); if (target == to && data.weight < smallest_weight && std::forward<FilterFunction>(filter)(data)) { smallest_edge = edge; smallest_weight = data.weight; } } return smallest_edge; }
int main(int argc, char *argv[]) { LogPolicy::GetInstance().Unmute(); try { // enable logging if (argc < 3) { SimpleLogger().Write(logWARNING) << "usage:\n" << argv[0] << " <osrm> <osrm.restrictions>"; return -1; } SimpleLogger().Write() << "Using restrictions from file: " << argv[2]; std::ifstream restriction_ifstream(argv[2], std::ios::binary); const FingerPrint fingerprint_orig; FingerPrint fingerprint_loaded; restriction_ifstream.read((char *)&fingerprint_loaded, sizeof(FingerPrint)); // check fingerprint and warn if necessary if (!fingerprint_loaded.TestGraphUtil(fingerprint_orig)) { SimpleLogger().Write(logWARNING) << argv[2] << " was prepared with a different build. " "Reprocess to get rid of this warning."; } if (!restriction_ifstream.good()) { throw osrm::exception("Could not access <osrm-restrictions> files"); } uint32_t usable_restrictions = 0; restriction_ifstream.read((char *)&usable_restrictions, sizeof(uint32_t)); restriction_list.resize(usable_restrictions); // load restrictions if (usable_restrictions > 0) { restriction_ifstream.read((char *)&(restriction_list[0]), usable_restrictions * sizeof(TurnRestriction)); } restriction_ifstream.close(); std::ifstream input_stream(argv[1], std::ifstream::in | std::ifstream::binary); if (!input_stream.is_open()) { throw osrm::exception("Cannot open osrm file"); } // load graph data std::vector<ImportEdge> edge_list; const NodeID number_of_nodes = readBinaryOSRMGraphFromStream(input_stream, edge_list, bollard_node_list, traffic_lights_list, &coordinate_list, restriction_list); input_stream.close(); BOOST_ASSERT_MSG(restriction_list.size() == usable_restrictions, "size of restriction_list changed"); SimpleLogger().Write() << restriction_list.size() << " restrictions, " << bollard_node_list.size() << " bollard nodes, " << traffic_lights_list.size() << " traffic lights"; traffic_lights_list.clear(); traffic_lights_list.shrink_to_fit(); // Building an node-based graph DeallocatingVector<TarjanEdge> graph_edge_list; for (const NodeBasedEdge &input_edge : edge_list) { if (input_edge.source == input_edge.target) { continue; } if (input_edge.forward) { graph_edge_list.emplace_back(input_edge.source, input_edge.target, (std::max)((int)input_edge.weight, 1), input_edge.name_id); } if (input_edge.backward) { graph_edge_list.emplace_back(input_edge.target, input_edge.source, (std::max)((int)input_edge.weight, 1), input_edge.name_id); } } edge_list.clear(); edge_list.shrink_to_fit(); BOOST_ASSERT_MSG(0 == edge_list.size() && 0 == edge_list.capacity(), "input edge vector not properly deallocated"); tbb::parallel_sort(graph_edge_list.begin(), graph_edge_list.end()); auto graph = std::make_shared<TarjanDynamicGraph>(number_of_nodes, graph_edge_list); edge_list.clear(); edge_list.shrink_to_fit(); SimpleLogger().Write() << "Starting SCC graph traversal"; RestrictionMap restriction_map(restriction_list); auto tarjan = osrm::make_unique<TarjanSCC<TarjanDynamicGraph>>(graph, restriction_map, bollard_node_list); tarjan->run(); SimpleLogger().Write() << "identified: " << tarjan->get_number_of_components() << " many components"; SimpleLogger().Write() << "identified " << tarjan->get_size_one_count() << " SCCs of size 1"; // output TIMER_START(SCC_RUN_SETUP); // remove files from previous run if exist DeleteFileIfExists("component.dbf"); DeleteFileIfExists("component.shx"); DeleteFileIfExists("component.shp"); Percent p(graph->GetNumberOfNodes()); OGRRegisterAll(); const char *pszDriverName = "ESRI Shapefile"; OGRSFDriver *poDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(pszDriverName); if (nullptr == poDriver) { throw osrm::exception("ESRI Shapefile driver not available"); } OGRDataSource *poDS = poDriver->CreateDataSource("component.shp", nullptr); if (nullptr == poDS) { throw osrm::exception("Creation of output file failed"); } OGRSpatialReference *poSRS = new OGRSpatialReference(); poSRS->importFromEPSG(4326); OGRLayer *poLayer = poDS->CreateLayer("component", poSRS, wkbLineString, nullptr); if (nullptr == poLayer) { throw osrm::exception("Layer creation failed."); } TIMER_STOP(SCC_RUN_SETUP); SimpleLogger().Write() << "shapefile setup took " << TIMER_MSEC(SCC_RUN_SETUP)/1000. << "s"; uint64_t total_network_distance = 0; p.reinit(graph->GetNumberOfNodes()); TIMER_START(SCC_OUTPUT); for (const NodeID source : osrm::irange(0u, graph->GetNumberOfNodes())) { p.printIncrement(); for (const auto current_edge : graph->GetAdjacentEdgeRange(source)) { const TarjanDynamicGraph::NodeIterator target = graph->GetTarget(current_edge); if (source < target || graph->EndEdges(target) == graph->FindEdge(target, source)) { total_network_distance += 100 * FixedPointCoordinate::ApproximateEuclideanDistance( coordinate_list[source].lat, coordinate_list[source].lon, coordinate_list[target].lat, coordinate_list[target].lon); BOOST_ASSERT(current_edge != SPECIAL_EDGEID); BOOST_ASSERT(source != SPECIAL_NODEID); BOOST_ASSERT(target != SPECIAL_NODEID); const unsigned size_of_containing_component = std::min(tarjan->get_component_size(source), tarjan->get_component_size(target)); // edges that end on bollard nodes may actually be in two distinct components if (size_of_containing_component < 1000) { OGRLineString lineString; lineString.addPoint(coordinate_list[source].lon / COORDINATE_PRECISION, coordinate_list[source].lat / COORDINATE_PRECISION); lineString.addPoint(coordinate_list[target].lon / COORDINATE_PRECISION, coordinate_list[target].lat / COORDINATE_PRECISION); OGRFeature *poFeature = OGRFeature::CreateFeature(poLayer->GetLayerDefn()); poFeature->SetGeometry(&lineString); if (OGRERR_NONE != poLayer->CreateFeature(poFeature)) { throw osrm::exception("Failed to create feature in shapefile."); } OGRFeature::DestroyFeature(poFeature); } } } } OGRSpatialReference::DestroySpatialReference(poSRS); OGRDataSource::DestroyDataSource(poDS); TIMER_STOP(SCC_OUTPUT); SimpleLogger().Write() << "generating output took: " << TIMER_MSEC(SCC_OUTPUT)/1000. << "s"; SimpleLogger().Write() << "total network distance: " << (uint64_t)total_network_distance / 100 / 1000. << " km"; SimpleLogger().Write() << "finished component analysis"; } catch (const std::exception &e) { SimpleLogger().Write(logWARNING) << "[exception] " << e.what(); } return 0; }
int main(int argc, char *argv[]) { std::vector<osrm::extractor::QueryNode> coordinate_list; osrm::util::LogPolicy::GetInstance().Unmute(); // enable logging if (argc < 2) { osrm::util::Log(logWARNING) << "usage:\n" << argv[0] << " <osrm>"; return EXIT_FAILURE; } std::vector<osrm::tools::TarjanEdge> graph_edge_list; auto number_of_nodes = osrm::tools::loadGraph(std::string(argv[1]), coordinate_list, graph_edge_list); tbb::parallel_sort(graph_edge_list.begin(), graph_edge_list.end()); const auto graph = std::make_shared<osrm::tools::TarjanGraph>(number_of_nodes, graph_edge_list); graph_edge_list.clear(); graph_edge_list.shrink_to_fit(); osrm::util::Log() << "Starting SCC graph traversal"; auto tarjan = std::make_unique<osrm::extractor::TarjanSCC<osrm::tools::TarjanGraph>>(graph); tarjan->Run(); osrm::util::Log() << "identified: " << tarjan->GetNumberOfComponents() << " many components"; osrm::util::Log() << "identified " << tarjan->GetSizeOneCount() << " size 1 SCCs"; // output TIMER_START(SCC_RUN_SETUP); // remove files from previous run if exist osrm::tools::deleteFileIfExists("component.dbf"); osrm::tools::deleteFileIfExists("component.shx"); osrm::tools::deleteFileIfExists("component.shp"); OGRRegisterAll(); const char *psz_driver_name = "ESRI Shapefile"; auto *po_driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(psz_driver_name); if (nullptr == po_driver) { throw osrm::util::exception("ESRI Shapefile driver not available" + SOURCE_REF); } auto *po_datasource = po_driver->CreateDataSource("component.shp", nullptr); if (nullptr == po_datasource) { throw osrm::util::exception("Creation of output file failed" + SOURCE_REF); } auto *po_srs = new OGRSpatialReference(); po_srs->importFromEPSG(4326); auto *po_layer = po_datasource->CreateLayer("component", po_srs, wkbLineString, nullptr); if (nullptr == po_layer) { throw osrm::util::exception("Layer creation failed." + SOURCE_REF); } TIMER_STOP(SCC_RUN_SETUP); osrm::util::Log() << "shapefile setup took " << TIMER_MSEC(SCC_RUN_SETUP) / 1000. << "s"; TIMER_START(SCC_OUTPUT); uint64_t total_network_length = 0; { osrm::util::UnbufferedLog log; log << "Constructing geometry "; osrm::util::Percent percentage(log, graph->GetNumberOfNodes()); for (const NodeID source : osrm::util::irange(0u, graph->GetNumberOfNodes())) { percentage.PrintIncrement(); for (const auto current_edge : graph->GetAdjacentEdgeRange(source)) { const auto target = graph->GetTarget(current_edge); if (source < target || SPECIAL_EDGEID == graph->FindEdge(target, source)) { total_network_length += 100 * osrm::util::coordinate_calculation::greatCircleDistance( coordinate_list[source], coordinate_list[target]); BOOST_ASSERT(current_edge != SPECIAL_EDGEID); BOOST_ASSERT(source != SPECIAL_NODEID); BOOST_ASSERT(target != SPECIAL_NODEID); const unsigned size_of_containing_component = std::min(tarjan->GetComponentSize(tarjan->GetComponentID(source)), tarjan->GetComponentSize(tarjan->GetComponentID(target))); // edges that end on bollard nodes may actually be in two distinct components if (size_of_containing_component < 1000) { OGRLineString line_string; line_string.addPoint(static_cast<double>(osrm::util::toFloating( coordinate_list[source].lon)), static_cast<double>(osrm::util::toFloating( coordinate_list[source].lat))); line_string.addPoint(static_cast<double>(osrm::util::toFloating( coordinate_list[target].lon)), static_cast<double>(osrm::util::toFloating( coordinate_list[target].lat))); OGRFeature *po_feature = OGRFeature::CreateFeature(po_layer->GetLayerDefn()); po_feature->SetGeometry(&line_string); if (OGRERR_NONE != po_layer->CreateFeature(po_feature)) { throw osrm::util::exception("Failed to create feature in shapefile." + SOURCE_REF); } OGRFeature::DestroyFeature(po_feature); } } } } } OGRSpatialReference::DestroySpatialReference(po_srs); OGRDataSource::DestroyDataSource(po_datasource); TIMER_STOP(SCC_OUTPUT); osrm::util::Log() << "generating output took: " << TIMER_MSEC(SCC_OUTPUT) / 1000. << "s"; osrm::util::Log() << "total network distance: " << static_cast<uint64_t>(total_network_length / 100 / 1000.) << " km"; osrm::util::Log() << "finished component analysis"; return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { LogPolicy::GetInstance().Unmute(); try { if (argc != 2) { SimpleLogger().Write(logWARNING) << "usage: " << argv[0] << " <file.hsgr>"; return 1; } boost::filesystem::path hsgr_path(argv[1]); std::vector<QueryGraph::NodeArrayEntry> node_list; std::vector<QueryGraph::EdgeArrayEntry> edge_list; SimpleLogger().Write() << "loading graph from " << hsgr_path.string(); unsigned m_check_sum = 0; unsigned m_number_of_nodes = readHSGRFromStream(hsgr_path, node_list, edge_list, &m_check_sum); SimpleLogger().Write() << "expecting " << m_number_of_nodes << " nodes, checksum: " << m_check_sum; BOOST_ASSERT_MSG(0 != node_list.size(), "node list empty"); SimpleLogger().Write() << "loaded " << node_list.size() << " nodes and " << edge_list.size() << " edges"; auto m_query_graph = std::make_shared<QueryGraph>(node_list, edge_list); BOOST_ASSERT_MSG(0 == node_list.size(), "node list not flushed"); BOOST_ASSERT_MSG(0 == edge_list.size(), "edge list not flushed"); Percent progress(m_query_graph->GetNumberOfNodes()); for (const auto node_u : osrm::irange(0u, m_query_graph->GetNumberOfNodes())) { for (const auto eid : m_query_graph->GetAdjacentEdgeRange(node_u)) { const EdgeData &data = m_query_graph->GetEdgeData(eid); if (!data.shortcut) { continue; } const unsigned node_v = m_query_graph->GetTarget(eid); const EdgeID edge_id_1 = m_query_graph->FindEdgeInEitherDirection(node_u, data.id); if (SPECIAL_EDGEID == edge_id_1) { throw osrm::exception("cannot find first segment of edge (" + std::to_string(node_u) + "," + std::to_string(data.id) + "," + std::to_string(node_v) + "), eid: " + std::to_string(eid)); } const EdgeID edge_id_2 = m_query_graph->FindEdgeInEitherDirection(data.id, node_v); if (SPECIAL_EDGEID == edge_id_2) { throw osrm::exception("cannot find second segment of edge (" + std::to_string(node_u) + "," + std::to_string(data.id) + "," + std::to_string(node_v) + "), eid: " + std::to_string(eid)); } } progress.printStatus(node_u); } m_query_graph.reset(); SimpleLogger().Write() << "Data file " << argv[0] << " appears to be OK"; } catch (const std::exception &e) { SimpleLogger().Write(logWARNING) << "[exception] " << e.what(); } return 0; }