int main(int argc, char *argv []) { TimeZoneAbbrevTable *tzabbr; TimestampTz tsz, eol; Timestamp ts; TimeTzADT *timetz; Interval *i; DateADT d; TimeADT time; char *s; pg_timezone_initialize(); if (!(tzabbr = load_tzoffsets("Default"))) warnx("failed to load Default"); else InstallTimeZoneAbbrevs(tzabbr); warnx("test..."); session_timezone = pg_tzset("Europe/Amsterdam"); tsz = timestamptz_in("2012/1/1 00:20:01+05"); s = timestamptz_out(tsz); warnx("timestamptz: %s", s); ts = timestamp_in("2012/12/12 12:12:12"); s = timestamp_out(ts); warnx("timestamp: %s", s); i = interval_in("10h5m"); s = interval_out(i); warnx("interval: %s", s); i = interval_in("1000000 hours"); s = interval_out(interval_justify_interval(i)); warnx("lifetime: %s", s); d = date_in("1999/9/9"); s = date_out(d); warnx("date: %s", s); time = time_in("10:20"); s = time_out(time); warnx("time: %s", s); timetz = timetz_in("10:20"); s = timetz_out(timetz); warnx("timetz: %s", s); tsz = GetCurrentTimestamp(); s = timestamptz_out(tsz); warnx("timestamptz: %s (now)", s); eol = timestamptz_pl_interval(tsz, interval_justify_interval(i)); s = timestamptz_out(eol); warnx("eol: %s", s); session_timezone = pg_tzset("Canada/Mountain"); s = timestamptz_out(tsz); warnx("timestamptz in canada: %s", s); return EX_OK; }
/** * TODO: Refactor this function into smaller functions for better readability. * * This function is the entry point for the whole extraction process. The goal of the extraction * step is to filter and convert the OSM geometry to something more fitting for routing. * That includes: * - extracting turn restrictions * - splitting ways into (directional!) edge segments * - checking if nodes are barriers or traffic signal * - discarding all tag information: All relevant type information for nodes/ways * is extracted at this point. * * The result of this process are the following files: * .names : Names of all streets, stored as long consecutive string with prefix sum based index * .osrm : Nodes and edges in a intermediate format that easy to digest for osrm-prepare * .restrictions : Turn restrictions that are used my osrm-prepare to construct the edge-expanded graph * */ int extractor::run(const ExtractorConfig &extractor_config) { try { LogPolicy::GetInstance().Unmute(); TIMER_START(extracting); const unsigned recommended_num_threads = tbb::task_scheduler_init::default_num_threads(); const auto number_of_threads = std::min(recommended_num_threads, extractor_config.requested_num_threads); tbb::task_scheduler_init init(number_of_threads); SimpleLogger().Write() << "Input file: " << extractor_config.input_path.filename().string(); SimpleLogger().Write() << "Profile: " << extractor_config.profile_path.filename().string(); SimpleLogger().Write() << "Threads: " << number_of_threads; // setup scripting environment ScriptingEnvironment scripting_environment(extractor_config.profile_path.string().c_str()); ExtractionContainers extraction_containers; auto extractor_callbacks = osrm::make_unique<ExtractorCallbacks>(extraction_containers); const osmium::io::File input_file(extractor_config.input_path.string()); osmium::io::Reader reader(input_file); const osmium::io::Header header = reader.header(); std::atomic<unsigned> number_of_nodes{0}; std::atomic<unsigned> number_of_ways{0}; std::atomic<unsigned> number_of_relations{0}; std::atomic<unsigned> number_of_others{0}; SimpleLogger().Write() << "Parsing in progress.."; TIMER_START(parsing); std::string generator = header.get("generator"); if (generator.empty()) { generator = "unknown tool"; } SimpleLogger().Write() << "input file generated by " << generator; // write .timestamp data file std::string timestamp = header.get("osmosis_replication_timestamp"); if (timestamp.empty()) { timestamp = "n/a"; } SimpleLogger().Write() << "timestamp: " << timestamp; boost::filesystem::ofstream timestamp_out(extractor_config.timestamp_file_name); timestamp_out.write(timestamp.c_str(), timestamp.length()); timestamp_out.close(); // initialize vectors holding parsed objects tbb::concurrent_vector<std::pair<std::size_t, ExtractionNode>> resulting_nodes; tbb::concurrent_vector<std::pair<std::size_t, ExtractionWay>> resulting_ways; tbb::concurrent_vector<mapbox::util::optional<InputRestrictionContainer>> resulting_restrictions; // setup restriction parser const RestrictionParser restriction_parser(scripting_environment.get_lua_state()); while (const osmium::memory::Buffer buffer = reader.read()) { // create a vector of iterators into the buffer std::vector<osmium::memory::Buffer::const_iterator> osm_elements; for (auto iter = std::begin(buffer); iter != std::end(buffer); ++iter) { osm_elements.push_back(iter); } // clear resulting vectors resulting_nodes.clear(); resulting_ways.clear(); resulting_restrictions.clear(); // parse OSM entities in parallel, store in resulting vectors tbb::parallel_for( tbb::blocked_range<std::size_t>(0, osm_elements.size()), [&](const tbb::blocked_range<std::size_t> &range) { ExtractionNode result_node; ExtractionWay result_way; lua_State *local_state = scripting_environment.get_lua_state(); for (auto x = range.begin(); x != range.end(); ++x) { const auto entity = osm_elements[x]; switch (entity->type()) { case osmium::item_type::node: result_node.clear(); ++number_of_nodes; luabind::call_function<void>( local_state, "node_function", boost::cref(static_cast<const osmium::Node &>(*entity)), boost::ref(result_node)); resulting_nodes.push_back(std::make_pair(x, result_node)); break; case osmium::item_type::way: result_way.clear(); ++number_of_ways; luabind::call_function<void>( local_state, "way_function", boost::cref(static_cast<const osmium::Way &>(*entity)), boost::ref(result_way)); resulting_ways.push_back(std::make_pair(x, result_way)); break; case osmium::item_type::relation: ++number_of_relations; resulting_restrictions.push_back(restriction_parser.TryParse( static_cast<const osmium::Relation &>(*entity))); break; default: ++number_of_others; break; } } }); // put parsed objects thru extractor callbacks for (const auto &result : resulting_nodes) { extractor_callbacks->ProcessNode( static_cast<const osmium::Node &>(*(osm_elements[result.first])), result.second); } for (const auto &result : resulting_ways) { extractor_callbacks->ProcessWay( static_cast<const osmium::Way &>(*(osm_elements[result.first])), result.second); } for (const auto &result : resulting_restrictions) { extractor_callbacks->ProcessRestriction(result); } } TIMER_STOP(parsing); SimpleLogger().Write() << "Parsing finished after " << TIMER_SEC(parsing) << " seconds"; SimpleLogger().Write() << "Raw input contains " << number_of_nodes.load() << " nodes, " << number_of_ways.load() << " ways, and " << number_of_relations.load() << " relations, and " << number_of_others.load() << " unknown entities"; extractor_callbacks.reset(); if (extraction_containers.all_edges_list.empty()) { SimpleLogger().Write(logWARNING) << "The input data is empty, exiting."; return 1; } extraction_containers.PrepareData(extractor_config.output_file_name, extractor_config.restriction_file_name); TIMER_STOP(extracting); SimpleLogger().Write() << "extraction finished after " << TIMER_SEC(extracting) << "s"; SimpleLogger().Write() << "To prepare the data for routing, run: " << "./osrm-prepare " << extractor_config.output_file_name << std::endl; } catch (std::exception &e) { SimpleLogger().Write(logWARNING) << e.what(); return 1; } return 0; }