diff --git a/cache.h b/cache.h index dbc22f0..d2cd8ee 100644 --- a/cache.h +++ b/cache.h @@ -81,15 +81,8 @@ public: float distance() const; }; -class CacheCmp { -public: - bool operator()(const Cache& lhs, const Cache& rhs) const { - return lhs.code < rhs.code; - } -}; - -typedef std::set Caches; +typedef std::vector Caches; +typedef std::vector pCaches; typedef std::multimap Date_Caches; -typedef std::vector Sorted_Caches; float cache_distance(const Cache& a, const Cache& b); diff --git a/geostat.cpp b/geostat.cpp index 67cb17b..ef7586d 100644 --- a/geostat.cpp +++ b/geostat.cpp @@ -173,44 +173,51 @@ int main(int argc, char** argv) { if (!ocpl_user_uuid.empty() || !ocpl_user.empty()) { 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)); + Caches tmp = OCpl.get_user_caches(ocpl_user_uuid, 0); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); ocpl_user_profile = OCpl.get_profile_url(ocpl_user_uuid); } if (!ocde_user_uuid.empty() || !ocde_user.empty()) { Okapi OCde(ocde_url, ocde_key); if (!ocde_user.empty()) ocde_user_uuid = OCde.get_uuid(ocde_user); - cc.merge(OCde.get_user_caches(ocde_user_uuid, 0)); + Caches tmp = OCde.get_user_caches(ocde_user_uuid, 0); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); ocde_user_profile = OCde.get_profile_url(ocde_user_uuid); } if (!ocus_user_uuid.empty() || !ocus_user.empty()) { Okapi OCus(ocus_url, ocus_key); if (!ocus_user.empty()) ocus_user_uuid = OCus.get_uuid(ocus_user); - cc.merge(OCus.get_user_caches(ocus_user_uuid, 0)); + Caches tmp = OCus.get_user_caches(ocus_user_uuid, 0); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); ocus_user_profile = OCus.get_profile_url(ocus_user_uuid); } if (!ocnl_user_uuid.empty() || !ocnl_user.empty()) { Okapi OCnl(ocnl_url, ocnl_key); if (!ocnl_user.empty()) ocnl_user_uuid = OCnl.get_uuid(ocnl_user); - cc.merge(OCnl.get_user_caches(ocnl_user_uuid, 0)); + Caches tmp = OCnl.get_user_caches(ocnl_user_uuid, 0); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); ocnl_user_profile = OCnl.get_profile_url(ocnl_user_uuid); } if (!ocro_user_uuid.empty() || !ocro_user.empty()) { Okapi OCro(ocro_url, ocro_key); if (!ocro_user.empty()) ocro_user_uuid = OCro.get_uuid(ocro_user); - cc.merge(OCro.get_user_caches(ocro_user_uuid, 0)); + Caches tmp = OCro.get_user_caches(ocro_user_uuid, 0); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); ocro_user_profile = OCro.get_profile_url(ocro_user_uuid); } if (!ocuk_user_uuid.empty() || !ocuk_user.empty()) { Okapi OCuk(ocuk_url, ocuk_key); if (!ocuk_user.empty()) ocuk_user_uuid = OCuk.get_uuid(ocuk_user); - cc.merge(OCuk.get_user_caches(ocuk_user_uuid, 0)); + Caches tmp = OCuk.get_user_caches(ocuk_user_uuid, 0); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); ocuk_user_profile = OCuk.get_profile_url(ocuk_user_uuid); } } if (!gpx_file.empty()) { GPX gpxfile(gpx_file); - cc.merge(gpxfile.get_user_caches()); + Caches tmp = gpxfile.get_user_caches(); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); } if (use_ocpl_db) { @@ -220,9 +227,11 @@ int main(int argc, char** argv) { ocpl_user_uuid = OCpl.get_uuid(ocpl_user); } if (get_not_found) { - cc.merge(db.get_user_caches_not_found(ocpl_user_uuid)); + Caches tmp = db.get_user_caches_not_found(ocpl_user_uuid); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); } else { - cc.merge(db.get_user_caches(ocpl_user_uuid, 0)); + Caches tmp = db.get_user_caches(ocpl_user_uuid, 0); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); } } @@ -239,10 +248,10 @@ int main(int argc, char** argv) { Date_Caches sorted_caches; Date_Caches sorted_fcaches; Date_Caches sorted_caches_by_hidden; - Sorted_Caches caches_by_fav; - Sorted_Caches caches_by_fav_perc; - Sorted_Caches caches_by_finds; - Caches fcc; + pCaches caches_by_fav; + pCaches caches_by_fav_perc; + pCaches caches_by_finds; + pCaches fcc; if (!get_not_found) { for (auto i = cc.begin(); i != cc.end(); ) { @@ -254,7 +263,7 @@ int main(int argc, char** argv) { sorted_caches.insert({ i->date_t, &*i }); if (i->type != "Moving" && i->type != "Own" && (!get_not_found || !exclude_quiz || i->type != "Quiz")) { sorted_fcaches.insert({ i->date_t, &*i }); - fcc.insert(*i); + fcc.push_back(&*i); } sorted_caches_by_hidden.insert({ i->date_hidden_t, &*i }); caches_by_fav.push_back(&*i); @@ -269,7 +278,7 @@ int main(int argc, char** argv) { } else { for (auto& i : cc) { if (i.type != "Moving" && i.type != "Own" && (!get_not_found || !exclude_quiz || i.type != "Quiz")) { - fcc.insert(i); + fcc.push_back(&i); } } } @@ -351,10 +360,10 @@ int main(int argc, char** argv) { std::cout << "Average distance between caches: " << tot_dist / (sorted_fcaches.size() - 1) << " km
\n"; std::cout << "\n"; - auto N = std::max_element(fcc.begin(), fcc.end(), [&](const Cache& a, const Cache& b) { return a.pos.lat < b.pos.lat; }); - auto S = std::min_element(fcc.begin(), fcc.end(), [&](const Cache& a, const Cache& b) { return a.pos.lat < b.pos.lat; }); - auto E = std::max_element(fcc.begin(), fcc.end(), [&](const Cache& a, const Cache& b) { return a.pos.lon < b.pos.lon; }); - auto W = std::min_element(fcc.begin(), fcc.end(), [&](const Cache& a, const Cache& b) { return a.pos.lon < b.pos.lon; }); + auto N = *std::max_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lat < b->pos.lat; }); + auto S = *std::min_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lat < b->pos.lat; }); + auto E = *std::max_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lon < b->pos.lon; }); + auto W = *std::min_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lon < b->pos.lon; }); std::cout << "

Geographically extreme caches

\n"; std::cout << "\n"; diff --git a/geostat_cli.cpp b/geostat_cli.cpp index dfb1da7..811ea6d 100644 --- a/geostat_cli.cpp +++ b/geostat_cli.cpp @@ -183,38 +183,45 @@ int main(int argc, char** argv) { if (!ocpl_user_uuid.empty() || !ocpl_user.empty()) { 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)); + Caches tmp = OCpl.get_user_caches(ocpl_user_uuid, 0); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); } if (!ocde_user_uuid.empty() || !ocde_user.empty()) { Okapi OCde(ocde_url, ocde_key); if (!ocde_user.empty()) ocde_user_uuid = OCde.get_uuid(ocde_user); - cc.merge(OCde.get_user_caches(ocde_user_uuid, 0)); + Caches tmp = OCde.get_user_caches(ocde_user_uuid, 0); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); } if (!ocus_user_uuid.empty() || !ocus_user.empty()) { Okapi OCus(ocus_url, ocus_key); if (!ocus_user.empty()) ocus_user_uuid = OCus.get_uuid(ocus_user); - cc.merge(OCus.get_user_caches(ocus_user_uuid, 0)); + Caches tmp = OCus.get_user_caches(ocus_user_uuid, 0); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); } if (!ocnl_user_uuid.empty() || !ocnl_user.empty()) { Okapi OCnl(ocnl_url, ocnl_key); if (!ocnl_user.empty()) ocnl_user_uuid = OCnl.get_uuid(ocnl_user); - cc.merge(OCnl.get_user_caches(ocnl_user_uuid, 0)); + Caches tmp = OCnl.get_user_caches(ocnl_user_uuid, 0); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); } if (!ocro_user_uuid.empty() || !ocro_user.empty()) { Okapi OCro(ocro_url, ocro_key); if (!ocro_user.empty()) ocro_user_uuid = OCro.get_uuid(ocro_user); - cc.merge(OCro.get_user_caches(ocro_user_uuid, 0)); + Caches tmp = OCro.get_user_caches(ocro_user_uuid, 0); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); } if (!ocuk_user_uuid.empty() || !ocuk_user.empty()) { Okapi OCuk(ocuk_url, ocuk_key); if (!ocuk_user.empty()) ocuk_user_uuid = OCuk.get_uuid(ocuk_user); - cc.merge(OCuk.get_user_caches(ocuk_user_uuid, 0)); + Caches tmp = OCuk.get_user_caches(ocuk_user_uuid, 0); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); } } if (!gpx_file.empty()) { GPX gpxfile(gpx_file); - cc.merge(gpxfile.get_user_caches()); + Caches tmp = gpxfile.get_user_caches(); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); } if (use_ocpl_db) { @@ -224,9 +231,11 @@ int main(int argc, char** argv) { ocpl_user_uuid = OCpl.get_uuid(ocpl_user); } if (get_not_found) { - cc.merge(db.get_user_caches_not_found(ocpl_user_uuid)); + Caches tmp = db.get_user_caches_not_found(ocpl_user_uuid); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); } else { - cc.merge(db.get_user_caches(ocpl_user_uuid, 0)); + Caches tmp = db.get_user_caches(ocpl_user_uuid, 0); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); } } @@ -241,20 +250,20 @@ int main(int argc, char** argv) { // Prepare sorted list of caches, excluding moving caches std::map dates; Date_Caches sorted_caches; - Caches fcc; + pCaches fcc; if (!get_not_found) { for (auto& i : cc) { dates[i.date]++; if (i.type != "Moving" && i.type != "Own") { sorted_caches.insert({ i.date_t, &i }); - fcc.insert(i); + fcc.push_back(&i); } } } else { for (auto& i : cc) { if (i.type != "Moving" && i.type != "Own") { - fcc.insert(i); + fcc.push_back(&i); } } } @@ -281,10 +290,10 @@ int main(int argc, char** argv) { if (!get_not_found) { if (show_minmax) { - auto N = std::max_element(fcc.begin(), fcc.end(), [&](const Cache& a, const Cache& b) { return a.pos.lat < b.pos.lat; }); - auto S = std::min_element(fcc.begin(), fcc.end(), [&](const Cache& a, const Cache& b) { return a.pos.lat < b.pos.lat; }); - auto E = std::max_element(fcc.begin(), fcc.end(), [&](const Cache& a, const Cache& b) { return a.pos.lon < b.pos.lon; }); - auto W = std::min_element(fcc.begin(), fcc.end(), [&](const Cache& a, const Cache& b) { return a.pos.lon < b.pos.lon; }); + auto N = *std::max_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lat < b->pos.lat; }); + auto S = *std::min_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lat < b->pos.lat; }); + auto E = *std::max_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lon < b->pos.lon; }); + auto W = *std::min_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lon < b->pos.lon; }); std::cout << "Most N:\n"; N->show(); @@ -297,8 +306,8 @@ int main(int argc, char** argv) { } if (show_dist) { - auto far = std::max_element(fcc.begin(), fcc.end(), [&](const Cache& a, const Cache& b) { return a.distance() < b.distance(); }); - auto near = std::min_element(fcc.begin(), fcc.end(), [&](const Cache& a, const Cache& b) { return a.distance() < b.distance(); }); + auto far = *std::max_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->distance() < b->distance(); }); + auto near = *std::min_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->distance() < b->distance(); }); std::cout << "Nearest cache: " << near->distance() << " km\n"; near->show(); diff --git a/gpx.cpp b/gpx.cpp index 94b3cb4..51cd3d5 100644 --- a/gpx.cpp +++ b/gpx.cpp @@ -76,7 +76,7 @@ Caches GPX::get_user_caches(__attribute__((unused)) const std::string& uuid, __a else if (c.code.starts_with("TR") || c.code.starts_with("VI") || c.code.starts_with("MV")) c.origin = "GC.su"; - list.insert(c); + list.push_back(c); } } Debug(2) << "Caches read from GPX file: " << list.size() << '\n'; diff --git a/heat.cpp b/heat.cpp index 4ae8aaf..70e7ab2 100644 --- a/heat.cpp +++ b/heat.cpp @@ -18,14 +18,14 @@ Heat::Heat(const Map* m) : mp(m) { #endif } -void Heat::generate(const std::string& filename, const Caches& points, int stamp_size, const std::string& theme) { +void Heat::generate(const std::string& filename, const pCaches& points, int stamp_size, const std::string& theme) { heatmap_t* hm = heatmap_new(mp->size_x, mp->size_y); heatmap_stamp_t* stamp = heatmap_stamp_gen(stamp_size); std::vector image(mp->size_x * mp->size_y * 4); for (auto el : points) { - if (mp->contains(Position(el.pos.lat, el.pos.lon))) { - heatmap_add_point_with_stamp(hm, mp->coordinate_x(Position(el.pos.lat, el.pos.lon)), mp->coordinate_y(Position(el.pos.lat, el.pos.lon)), stamp); + if (mp->contains(Position(el->pos.lat, el->pos.lon))) { + heatmap_add_point_with_stamp(hm, mp->coordinate_x(Position(el->pos.lat, el->pos.lon)), mp->coordinate_y(Position(el->pos.lat, el->pos.lon)), stamp); // std::cout << mp->coordinate_x(Position(el.pos.lon, el.pos.lat)) << '\t' << mp->coordinate_y(Position(el.pos.lon, el.pos.lat)) << '\n'; } } diff --git a/heat.h b/heat.h index 9cd8ac0..75fee4e 100644 --- a/heat.h +++ b/heat.h @@ -13,6 +13,6 @@ private: public: explicit Heat(const Map* m); - void generate(const std::string& filename, const Caches& points, int stamp_size, const std::string& theme = "soft"); + void generate(const std::string& filename, const pCaches& points, int stamp_size, const std::string& theme = "soft"); void generate_path(const std::string& filename, const Date_Caches& sorted); }; diff --git a/ocdb.cpp b/ocdb.cpp index 7e0569c..464660c 100644 --- a/ocdb.cpp +++ b/ocdb.cpp @@ -308,7 +308,7 @@ Caches OCdb::get_user_caches_not_found(const std::string& uuid) const { while (res == SQLITE_ROW) { c.code = reinterpret_cast(sqlite3_column_text(stmt, 0)); c.pos = get_lat_lon(reinterpret_cast(sqlite3_column_text(stmt, 1))); - cc.insert(c); + cc.push_back(c); res = sqlite3_step(stmt); } @@ -347,7 +347,7 @@ Caches OCdb::get_user_caches(const std::string& uuid, __attribute__((unused)) in //c.country = reinterpret_cast(sqlite3_column_text(stmt, 6)); c.region = reinterpret_cast(sqlite3_column_text(stmt, 7)); c.owner_uuid = reinterpret_cast(sqlite3_column_text(stmt, 8)); // TODO: we don't know owner's nick - cc.insert(c); + cc.push_back(c); res = sqlite3_step(stmt); } diff --git a/okapi.cpp b/okapi.cpp index f7254e7..31c1dba 100644 --- a/okapi.cpp +++ b/okapi.cpp @@ -117,7 +117,7 @@ std::string Okapi::get_caches_json(const std::string& codes) const { // return c; // } -Caches Okapi::get_caches(const std::map& codes) const { +Caches Okapi::get_caches(const std::vector& codes) const { Cache c; Caches cc; @@ -130,7 +130,7 @@ Caches Okapi::get_caches(const std::map& codes) const { k = 0; while (it != codes.end() && k < 500) { - codes_list += it->first; + codes_list += *it; codes_list += '|'; it++; k++; @@ -161,10 +161,7 @@ Caches Okapi::get_caches(const std::map& codes) const { ss >> std::get_time(&tmp, "%Y-%m-%dT%H:%M:%S+"); c.set_date_hidden(tmp); - //ugly way to handle date... might produce bad results if a cache appears twice in the list - auto el2 = std::find_if(codes.begin(), codes.end(), [&](auto& e) { return e.first == c.code; }); - c.set_date(el2->second); - cc.insert(c); + cc.push_back(c); } } return cc; @@ -172,7 +169,13 @@ Caches Okapi::get_caches(const std::map& codes) const { Caches Okapi::get_user_caches(const std::string& uuid, int count) const { Caches cc; - std::map codes; + std::vector codes; + + struct extra_data { + std::tm date; + }; + std::map tmp_data; // holds data from logs which needs to be added to Caches later + json j; std::tm date; int off = 0; @@ -187,7 +190,8 @@ Caches Okapi::get_user_caches(const std::string& uuid, int count) const { std::stringstream ss(el.value()["date"].get()); // TODO need to take care of the time zone :/ ss >> std::get_time(&date, "%Y-%m-%dT%H:%M:%S+"); - codes[el.value()["cache_code"].get()] = date; + codes.push_back(el.value()["cache_code"].get()); + tmp_data[el.value()["cache_code"].get()] = { date }; } } off += j.size(); @@ -202,7 +206,8 @@ Caches Okapi::get_user_caches(const std::string& uuid, int count) const { if (el.value()["type"] == "Found it") { std::stringstream ss(el.value()["date"].get()); ss >> std::get_time(&date, "%Y-%m-%dT%H-%M-%S"); - codes[el.value()["cache_code"].get()] = date; + codes.push_back(el.value()["cache_code"].get()); + tmp_data[el.value()["cache_code"].get()] = { date }; } } off += j.size(); @@ -212,6 +217,16 @@ Caches Okapi::get_user_caches(const std::string& uuid, int count) const { cc = get_caches(codes); Debug(2) << "Caches read from OC: " << cc.size() << '\n'; + std::map mcc; + for (auto& i : cc) + mcc.insert( { i.code, i } ); + +// introduce extra data from the logs to Caches + for (auto& el : tmp_data) { + auto& it = mcc.at(el.first); + it.set_date(el.second.date); + } + return cc; } diff --git a/okapi.h b/okapi.h index cdf7119..48c49c3 100644 --- a/okapi.h +++ b/okapi.h @@ -23,7 +23,7 @@ public: Okapi(const std::string& server_url, const std::string& consumer_key); // Cache get_cache(std::string code); - Caches get_caches(const std::map& codes) const; + Caches get_caches(const std::vector& codes) const; Caches get_user_caches(const std::string& uuid, int count = 0) const override; std::string get_changelog_json(int revision) const;