diff --git a/README.md b/README.md
index 30c20f9..812db8e 100644
--- a/README.md
+++ b/README.md
@@ -37,6 +37,7 @@ Generate HTML stats from Opencaching data or GPX files.
-s n stamp size for a heat map (default = 15)
-e use exponential to flatten the heat map
-t draw trail instead of heat map
+ -a draw animated map instead of heat map
-m map chosen map: Poland, Poland_relief, Poland_big, Europe, World or a name of voivodeship (default = Poland)
-h display this help screen
```
diff --git a/geostat.cpp b/geostat.cpp
index 166319e..242317c 100644
--- a/geostat.cpp
+++ b/geostat.cpp
@@ -36,6 +36,7 @@ void show_usage() {
std::cout << "\t-s n\t\tstamp size for a heat map (default = 15)\n";
std::cout << "\t-e\t\tuse exponential to flatten the heat map\n";
std::cout << "\t-t\t\tdraw trail instead of heat map\n";
+ std::cout << "\t-a\t\tdraw animated map instead of heat map\n";
std::cout << "\t-m map\t\tchosen map: Poland, Poland_relief, Poland_big, Europe, World or a name of voivodeship (default = Poland)\n";
std::cout << "\t-h\t\tdisplay this help screen\n";
std::exit(EXIT_FAILURE);
@@ -47,6 +48,7 @@ int main(int argc, char** argv) {
std::string heat_map = "Poland";
bool heat_exp = 0;
bool trail = 0;
+ bool anim = 0;
bool use_oc = 0;
bool use_ocpl_db = 0;
bool get_not_found = 0;
@@ -86,7 +88,7 @@ int main(int argc, char** argv) {
if (argc == 1) show_usage();
int o;
- while ((o = getopt(argc, argv, "qNOQD:o::p:d:u:n:r:k:i:f:H:s:m:eth?")) != -1)
+ while ((o = getopt(argc, argv, "qNOQD:o::p:d:u:n:r:k:i:f:H:s:m:etah?")) != -1)
switch (o) {
case 'D':
Debug::set_debug_level(get_num('d', optarg));
@@ -158,6 +160,9 @@ int main(int argc, char** argv) {
case 't':
trail = 1;
break;
+ case 'a':
+ anim = 1;
+ break;
case 'h':
case '?':
default:
@@ -180,6 +185,12 @@ int main(int argc, char** argv) {
std::exit(EXIT_FAILURE);
}
}
+
+ if (trail && anim) {
+ std::cout << "Options \"-a\" and \"-t\" are mutually exclusive.\n";
+ std::exit(EXIT_FAILURE);
+ }
+
if (use_oc) {
if (!ocpl_user_uuid.empty() || !ocpl_user.empty()) {
Okapi OCpl(ocpl_url, ocpl_key);
@@ -240,6 +251,8 @@ int main(int argc, char** argv) {
}
if (get_not_found) {
Caches tmp = db.get_user_caches_not_found(ocpl_user_uuid);
+ Okapi OCpl(ocpl_url, ocpl_key);
+ OCpl.update_caches(tmp);
std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc));
region_count = db.get_region_stats();
} else if (get_owned) {
@@ -319,7 +332,7 @@ int main(int argc, char** argv) {
std::sort(caches_by_rating.begin(), caches_by_rating.end(), [&](const Cache* a, const Cache* b) { return a->rating > b->rating; });
} else {
for (auto& i : cc) {
- if (i.type != "Moving" && i.type != "Own" && (!exclude_quiz || i.type != "Quiz")) {
+ if (i.type != "Moving" && i.type != "Own" && (!exclude_quiz || i.type != "Quiz") && i.rating >= 4.9) {
fcc.push_back(&i);
poland.locate(i);
}
@@ -364,7 +377,9 @@ int main(int argc, char** argv) {
std::exit(EXIT_FAILURE);
}
hmap.generate_path(heat_file, sorted_fcaches);
- } else
+ } else if (anim)
+ hmap.generate_anim(heat_file, sorted_caches, 2);
+ else
hmap.generate(heat_file, fcc, heat_stamp_size, (heat_exp == 1 ? "exp" : "soft"));
std::cout << "\n";
}
diff --git a/geostat_cli.cpp b/geostat_cli.cpp
index a00d055..cbd12ab 100644
--- a/geostat_cli.cpp
+++ b/geostat_cli.cpp
@@ -34,6 +34,7 @@ void show_usage() {
std::cout << "\t-s n\t\tstamp size for a heat map (default = 15)\n";
std::cout << "\t-e\t\tuse exponential to flatten the heat map\n";
std::cout << "\t-t\t\tdraw trail instead of heat map\n";
+ std::cout << "\t-a\t\tdraw animated map instead of heat map\n";
std::cout << "\t-m map\t\tchosen map: Poland, Poland_relief, Poland_big, Europe, World or a name of voivodeship (default = Poland)\n";
std::cout << "\t-L\t\tprint all caches\n";
std::cout << "\t-T\t\tprint D/T matrix\n";
@@ -56,6 +57,7 @@ int main(int argc, char** argv) {
std::string heat_map = "Poland";
bool heat_exp = 0;
bool trail = 0;
+ bool anim = 0;
bool use_oc = 0;
bool use_ocpl_db = 0;
bool get_not_found = 0;
@@ -84,7 +86,7 @@ int main(int argc, char** argv) {
if (argc == 1) show_usage();
int o;
- while ((o = getopt(argc, argv, "qNOg:o::p:d:u:n:r:k:MDCH:s:m:etLTYh?")) != -1)
+ while ((o = getopt(argc, argv, "qNOg:o::p:d:u:n:r:k:MDCH:s:m:etaLTYh?")) != -1)
switch (o) {
// case 'd':
// Debug::set_debug_level(get_num('d',optarg));
@@ -160,6 +162,9 @@ int main(int argc, char** argv) {
case 't':
trail = 1;
break;
+ case 'a':
+ anim = 1;
+ break;
case 'L':
show_list = 1;
break;
@@ -188,6 +193,11 @@ int main(int argc, char** argv) {
}
}
+ if (trail && anim) {
+ std::cout << "Options \"-a\" and \"-t\" are mutually exclusive.\n";
+ std::exit(EXIT_FAILURE);
+ }
+
if (use_oc) {
if (!ocpl_user_uuid.empty() || !ocpl_user.empty()) {
Okapi OCpl(ocpl_url, ocpl_key);
@@ -311,6 +321,8 @@ int main(int argc, char** argv) {
Heat hmap(chosen_map);
if (trail)
hmap.generate_path(heat_file, sorted_caches);
+ else if (anim)
+ hmap.generate_anim(heat_file, sorted_caches, 2);
else
hmap.generate(heat_file, fcc, heat_stamp_size, (heat_exp == 1 ? "exp" : "soft"));
}
diff --git a/heat.cpp b/heat.cpp
index a849c89..cf64275 100644
--- a/heat.cpp
+++ b/heat.cpp
@@ -76,3 +76,34 @@ void Heat::generate_path(const std::string& filename, const Date_Caches& sorted)
contour.draw(draw);
contour.write(filename);
}
+
+void Heat::generate_anim(const std::string& filename, const Date_Caches& sorted, int dot_size) {
+ std::vector frames;
+ frames.emplace_back(MAPS_DIR / mp->map_file);
+
+ Magick::Image canvas(Magick::Geometry(mp->size_x, mp->size_y), "transparent");
+ canvas.strokeWidth(1);
+ canvas.gifDisposeMethod(1);
+ canvas.animationDelay(1);
+ canvas.animationIterations(1);
+
+ const Cache* prev = nullptr;
+
+ for (auto el = sorted.begin()++; el != sorted.end(); el++) {
+ if (mp->contains(Position(el->second->pos.lat, el->second->pos.lon))) {
+ canvas.erase();
+ if (prev) {
+ canvas.strokeColor("black");
+ canvas.fillColor("black");
+ canvas.draw(Magick::DrawableEllipse(mp->coordinate_x(Position(prev->pos.lat, prev->pos.lon)), mp->coordinate_y(Position(prev->pos.lat, prev->pos.lon)), dot_size, dot_size, 0, 360));
+ }
+ prev = el->second;
+ canvas.strokeColor("red");
+ canvas.fillColor("red");
+ canvas.draw(Magick::DrawableEllipse(mp->coordinate_x(Position(prev->pos.lat, prev->pos.lon)), mp->coordinate_y(Position(prev->pos.lat, prev->pos.lon)), dot_size, dot_size, 0, 360));
+ frames.push_back(canvas);
+ }
+ }
+
+ Magick::writeImages(frames.begin(), frames.end(), filename);
+}
diff --git a/heat.h b/heat.h
index 75fee4e..0e1508b 100644
--- a/heat.h
+++ b/heat.h
@@ -15,4 +15,5 @@ public:
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);
+ void generate_anim(const std::string& filename, const Date_Caches& sorted, int dot_size);
};