Rev 13 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* countries.cc
* DIN Is Noise is copyright (c) 2006-2017 Jagannathan Sampath
* For more information, please visit http://dinisnoise.org/
*/
#include "countries.h"
#include "vector2d.h"
#include <vector>
#include <fstream>
#include <algorithm>
#include "console.h"
using namespace std;
extern ofstream dlog;
extern string user_data_dir;
extern string country_data_dir;
extern const int MILLION;
extern console cons;
bool area::operator< (const area& rhs) const {
return num_vertices > rhs.num_vertices;
}
countries::countries () {
name = "Countries";
id = -1;
p_cur_country = 0;
area_id = 0;
change_curve_name = 1;
}
countries::~countries () {
widget_save ("d_countries", ctrls);
save_params ();
}
void countries::load_params () {
ifstream f (make_fname().c_str(), ios::in);
string ignore;
float step;
f >> ignore >> id >> ignore >> area_id >> ignore >> step;
sp_step.set_value (step);
load_country (index[id]);
}
void countries::save_params () {
ofstream f (make_fname().c_str(), ios::out);
if (f) {
f << "id " << id << endl;
f << "area_id " << area_id << endl;
f << "step " << int(sp_step.f_value) << endl;
}
}
void countries::load_index () {
string fname (country_data_dir + "index");
ifstream f (fname.c_str(), ios::in);
if (!f) {
dlog << "couldnt read from : " << fname << endl;
return;
}
f >> num_countries;
for (int i = 0; i < num_countries; ++i) {
f >> fname;
index.push_back (fname);
}
sort (index.begin (), index.end());
}
void countries::setup () {
plugin::setup ();
load_index ();
widget* _ctrls [] = {&ol_country, &ol_area, &sp_step, &lf_search};
for (int i = 0; i < 4; ++i) {
ctrls.push_back (_ctrls[i]);
_ctrls[i]->set_color (clr.r, clr.g, clr.b);
}
num_ctrls = ctrls.size ();
lf_search.set_label ("Country?");
lf_search.set_listener (this);
ol_country.set_text ("Country = ");
ol_country.set_listener (this);
ol_country.set_click_repeat (1);
ol_area.set_listener (this);
ol_area.set_click_repeat (1);
ol_area.set_text ("Area = ");
sp_step.set_label ("Step");
sp_step.set_limits (1, MILLION);
sp_step.set_delta (1);
sp_step.set_listener (this);
widget_load ("d_countries", ctrls);
load_params ();
lf_search.fld.set_text (index[id]);
//for (int i = 0; i < num_ctrls; ++i) ctrls[i]->set_moveable (1);
}
void countries::render () {
if (p_cur_country) {
points.clear ();
area& a0 = p_cur_country->areas[area_id];
float a0x = a0.x[0], a0y = a0.y[0];
point<float> pa0 (a0x, a0y);
points.push_back (pa0);
for (int i = 1, j = a0.num_vertices - 1, di = sp_step.f_value; i < j; i += di) points.push_back (point<float>(a0.x[i], a0.y[i]));
points.push_back (pa0);
ss.str("");
ss << p_cur_country->name;
}
}
country* countries::load_country (const string& which) {
country& c = the_countries [which];
if (c.num_areas == 0) {
string fname (country_data_dir + which);
ifstream f (fname.c_str(), ios::in);
if (!f) {
dlog << "couldnt load from : " << fname << endl;
return 0;
}
c.name = which;
string ignore;
while (!f.eof()) {
f >> ignore >> c.num_areas;
for (int i = 0; i < c.num_areas; ++i) {
c.areas.push_back (area());
area& ai = c.areas[i];
f >> ignore >> ai.num_vertices;
float l, b, r, t; f >> ignore >> l >> b >> r >> t;
ai.bbox (l, b, r, t);
for (int p = 0; p < ai.num_vertices; ++p) {
float x, y; f >> x >> y;
ai.x.push_back (x);
ai.y.push_back (y);
}
}
}
}
p_cur_country = &c;
set_country (which);
return &c;
}
void countries::picked (label& lbl, int dir) {
if (&lbl == &ol_country.option) {
id += dir;
if (id < 0) id = num_countries - 1; else if (id >= num_countries) id = 0;
string name (index[id]);
load_country (name);
} else if (&lbl == &ol_area.option) {
if (p_cur_country) {
area_id += dir;
render_area ();
}
}
}
void countries::changed (field& f) {
if (&f == &lf_search.fld) {
string name (f.text);
for (int i = 0, j = name.size (); i < j; ++i) if (name[i] == ' ') name[i]= '_';
//for (auto& i : name) if (i == ' ') i = '_';
int nid = find_id (name);
if (nid == -1) {
cons << console::red << "Couldnt find the country " << name << eol;
if (name == "") f.set_text (index[id]);
} else {
id = nid;
load_country (name);
}
} else {
render ();
if (cb_auto_apply.state) clicked (b_apply);
}
}
void countries::render_area () {
if (area_id < 0) area_id = p_cur_country->num_areas - 1; else if (area_id >= p_cur_country->num_areas) area_id = 0;
stringstream ss; ss << "Area " << (area_id+1) << " of " << p_cur_country->num_areas;
ol_area.set_text (ss.str());
render ();
if (cb_auto_apply.state) clicked (b_apply);
}
void countries::set_country (const string& name) {
ol_country.set_text (name);
area_id = 0;
render_area ();
}
int countries::find_id (const string& name) {
for (int i = 0, j = index.size (); i < j; ++i) {
if (index[i] == name) return i;
}
return -1;
}
void area::calc_bbox () {
if (num_vertices) {
float xmin = x[0], ymin = y[0], xmax = xmin, ymax = ymin;
for (int i = 1, j = num_vertices; i < j; ++i) {
float xi = x[i], yi = y[i];
if (xi < xmin) xmin = xi; else if (xi > xmax) xmax = xi;
if (yi < ymin) ymin = yi; else if (yi > ymax) ymax = yi;
}
bbox (xmin, ymin, xmax, ymax);
}
}
void area::normalise () {
float aspect_ratio = bbox.width * 1. / bbox.height;
float xw = aspect_ratio * 2.0f, xwh = xw / 2.0f;
for (int i = 0, j = num_vertices; i < j; ++i) {
float xi = x[i], yi = y[i];
float fx = (xi - bbox.left) * bbox.width_1;
float fy = (yi - bbox.bottom) * bbox.height_1;
float xj = -xwh + fx * xw;
float yj = -1 + fy * 2.0f;
x[i] = xj;
y[i] = yj;
}
bbox (-xwh, -1.0f, xwh, 1.0f);
}
/*void countries::load_data () { // load data from countries.dat and write individual country files in country sub directory
string fname (user_data_dir + "countries.dat");
ifstream f (fname.c_str(), ios::in);
if (!f) {
dlog << "!!! couldnt load from countries.dat !!!" << endl;
return;
}
country* pC = 0;
area* pA = 0;
float x, y;
string word;
int nc = 0, na = 0, nv = 0;
while (!f.eof()) {
f >> word;
if (word == "country") {
if (pC) {
pC->num_areas = na;
}
na = 0;
countrys.push_back (country());
nc = countrys.size ();
pC = &countrys[nc-1];
f >> pC->name;
} else if (word == "area") {
if (pA) pA->num_vertices = nv;
nv = 0;
pC->areas.push_back (area());
na = pC->areas.size();
pA = &pC->areas[na-1];
goto read_v;
} else if (word == "v") {
read_v:
f >> x >> y;
pA->x.push_back (x);
pA->y.push_back (y);
++nv;
}
}
if (pC) pC->num_areas = na;
if (pA) pA->num_vertices = nv;
ofstream fi ((country_data_dir + "index").c_str(), ios::out);
fi << countrys.size () << endl;
for (auto& c : countrys) {
fi << c.name << endl;
ofstream fc ((country_data_dir + c.name).c_str(), ios::out);
fc << "num_areas " << c.num_areas << endl;
std::sort (c.areas.begin (), c.areas.end());
for (auto& a : c.areas) {
fc << "num_vertices " << a.num_vertices << endl;
a.calc_bbox ();
a.normalise ();
fc << "bounding_box " << a.bbox.left << ' ' << a.bbox.bottom << ' ' << a.bbox.right << ' ' << a.bbox.top << endl;
for (int i = 0, j = a.num_vertices; i < j; ++i) {
fc << a.x[i] << ' ' << a.y[i] << endl;
}
}
}
}*/