#include "okapi.h" #include "gpx.h" #include "cache.h" #include "debug.h" #include "heat.h" #include #include #include #include int main(int argc, char** argv) { bool show_minmax = 0; bool show_dist = 0; bool show_list = 0; bool show_dt = 0; std::string heat_file; int heat_stamp_size = 15; std::string heat_map; bool use_ocpl = 0; std::string ocpl_user; std::string ocpl_url = "https://opencaching.pl/okapi/"; std::string gpx_file; #include "config_user.h" int o; while ((o = getopt(argc, argv, "g:d:pu:MDH:s:m:LTh")) != -1) switch (o) { case 'd': try { if (std::stoi(optarg) > 0) { // Debug(1) << "Setting debug level to " << optarg; Debug::set_debug_level(std::stoi(optarg)); } } catch (...) { std::cout << "Option \"-d\" requires a valid number as an argument\n"; std::exit(EXIT_FAILURE); } break; case 'g': gpx_file = optarg; break; case 'p': use_ocpl = 1; break; case 'u': ocpl_user = optarg; break; case 'M': show_minmax = 1; break; case 'D': show_dist = 1; break; case 'H': heat_file = optarg; break; case 's': try { if (std::stoi(optarg) > 0) { heat_stamp_size = std::stoi(optarg); } } catch (...) { std::cout << "Option \"-s\" requires a valid number as an argument\n"; std::exit(EXIT_FAILURE); } break; case 'm': heat_map = optarg; break; case 'L': show_list = 1; break; case 'T': show_dt = 1; break; case 'h': case '?': default: std::cout << "Usage: [-p] [-g file] [-MDHh]\n"; std::cout << "Generate stats from Opencaching data or GPX files.\n\n"; std::cout << " * Data source:\n"; std::cout << "\t-p\tuse Opencaching.pl\n"; std::cout << "\t-u user\tuser for Opencaching\n"; std::cout << "\t-g file\tuse specified gpx file\n"; std::cout << " * Output:\n"; std::cout << "\t-M\tprint geographically extreme caches\n"; std::cout << "\t-D\tprint furthest and closest caches\n"; std::cout << "\t-H file\trender a heat map to a file\n"; std::cout << "\t-s n\tstamp size for a heat map (default = 15)\n"; std::cout << "\t-m map\tchosen map: Poland, Poland_relief, Europe (default = Poland)\n"; std::cout << "\t-L\tprint all caches\n"; std::cout << "\t-T\tprint D/T matrix\n"; std::cout << "\t-h\tdisplay this help screen\n"; std::exit(EXIT_FAILURE); } Caches cc; if (use_ocpl) { Okapi OCpl(ocpl_url, ocpl_key); if (!ocpl_user.empty()) { ocpl_user_uuid = OCpl.get_uuid(ocpl_user); } cc.merge(OCpl.get_user_caches(ocpl_user_uuid, 0)); } if (!gpx_file.empty()) { GPX gpxfile(gpx_file); cc.merge(gpxfile.get_user_caches()); } // TODO: some cache deduplication is needed Debug(2) << "Caches read: " << cc.size() << '\n'; if (!heat_file.empty()) { const Map* chosen_map; if (heat_map == "Poland_relief") chosen_map = &Poland_relief; else if (heat_map == "Poland" || heat_map.empty()) chosen_map = &Poland; else if (heat_map == "Europe") chosen_map = &Europe; else { std::cout << "Map " << heat_map << " not found.\n"; std::exit(EXIT_FAILURE); } Heat hmap(&cc, chosen_map); hmap.generate(heat_file, heat_stamp_size); } if (show_minmax) { auto N = std::max_element(cc.begin(), cc.end(), CacheCmpNS); auto S = std::min_element(cc.begin(), cc.end(), CacheCmpNS); auto E = std::max_element(cc.begin(), cc.end(), CacheCmpEW); auto W = std::min_element(cc.begin(), cc.end(), CacheCmpEW); std::cout << "Most N:\n"; N->show(); std::cout << "Most S:\n"; S->show(); std::cout << "Most E:\n"; E->show(); std::cout << "Most W:\n"; W->show(); } if (show_dist) { auto far = std::max_element(cc.begin(), cc.end(), CacheCmpDist); auto near = std::min_element(cc.begin(), cc.end(), CacheCmpDist); std::cout << "Nearest cache: " << near->distance() << " km\n"; near->show(); std::cout << "Furthest cache: " << far->distance() << " km\n"; far->show(); } if (show_list) { for (auto el : cc) el.show(); } if (show_dt) { short dt_table[11][11]; std::cout << std::setw(5) << "D\\T"; for (int j = 2; j <= 10; j++) { // print table terr headers std::cout << std::setw(5) << j / 2.0; } std::cout << '\n'; for (int i = 2; i <= 10; i++) { // i -> diff in rows std::cout << std::setw(5) << i / 2.0; for (int j = 2; j <= 10; j++) { // j -> terr in cols dt_table[i][j] = std::count_if(cc.begin(), cc.end(), [i, j](Cache c) { return (c.diff == i / 2.0 && c.terr == j / 2.0); }); std::cout << std::setw(5) << dt_table[i][j]; } std::cout << '\n'; } } }