geostat/geostat.cpp

175 wiersze
4.2 KiB
C++

#include "okapi.h"
#include "gpx.h"
#include "cache.h"
#include "debug.h"
#include "heat.h"
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <unistd.h>
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;
bool heat_relief = 0;
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:rLTh")) != -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 'r':
heat_relief = 1;
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-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()) {
Heat hmap(&cc);
hmap.generate(heat_file, heat_stamp_size, heat_relief);
}
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();
std::cout << "Dist:\t" << far->distance() << " km\n";
}
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';
}
}
}