Initial support for animated GIFs instead of heatmaps

master
Tomasz Golinski 2020-11-02 21:01:27 +01:00
rodzic 32e1053c6b
commit 155943a6c9
5 zmienionych plików z 64 dodań i 4 usunięć

Wyświetl plik

@ -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
```

Wyświetl plik

@ -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 << "<figure>\n<img class=\"heatmap\" src=\"" << heat_file << "\" alt=\"heat map\">\n</figure>\n";
}

Wyświetl plik

@ -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"));
}

Wyświetl plik

@ -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<Magick::Image> 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);
}

1
heat.h
Wyświetl plik

@ -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);
};