kopia lustrzana https://gitlab.com/tomaszg/geostat
Initial support for animated GIFs instead of heatmaps
rodzic
32e1053c6b
commit
155943a6c9
|
@ -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
|
||||
```
|
||||
|
|
21
geostat.cpp
21
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 << "<figure>\n<img class=\"heatmap\" src=\"" << heat_file << "\" alt=\"heat map\">\n</figure>\n";
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
|
|
31
heat.cpp
31
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<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
1
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);
|
||||
};
|
||||
|
|
Ładowanie…
Reference in New Issue