Subversion Repositories DIN Is Noise

Rev

Rev 2107 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
964 jag 1
/*
2
* countries.cc
2302 jag 3
* DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath
1713 jag 4
* DIN Is Noise is released under GNU Public License 2.0
1479 jag 5
* For more information, please visit https://dinisnoise.org/
964 jag 6
*/
7
 
8
 
9
#include "countries.h"
10
#include "vector2d.h"
1579 jag 11
#include "console.h"
12
#include "log.h"
964 jag 13
#include <vector>
14
#include <fstream>
15
#include <algorithm>
16
using namespace std;
17
 
18
 
19
extern string user_data_dir;
20
extern string country_data_dir;
21
 
22
extern console cons;
23
 
24
bool area::operator< (const area& rhs) const {
25
 return num_vertices > rhs.num_vertices;
26
}
27
 
28
countries::countries () {
29
  name = "Countries";
30
  id = -1;
31
  p_cur_country = 0;
32
  area_id = 0;
33
  change_curve_name = 1;
34
}
35
 
36
countries::~countries () {
37
  widget_save ("d_countries", ctrls);
38
  save_params ();
39
}
40
 
41
void countries::load_params () {
42
  ifstream f (make_fname().c_str(), ios::in);
43
  string ignore;
44
  float step;
45
  f >> ignore >> id >> ignore >> area_id >> ignore >> step;
1579 jag 46
  pt.step.set_value (step);
964 jag 47
  load_country (index[id]);
48
}
49
 
50
void countries::save_params () {
51
  ofstream f (make_fname().c_str(), ios::out);
52
  if (f) {
53
    f << "id " << id << endl;
54
    f << "area_id " << area_id << endl;
2107 jag 55
    f << "step " << int(pt.step.value) << endl;
964 jag 56
  }
57
}
58
 
59
void countries::load_index () {
60
  string fname (country_data_dir + "index");
61
  ifstream f (fname.c_str(), ios::in);
62
  if (!f) {
63
    dlog << "couldnt read from : " << fname << endl;
64
    return;
65
  }
66
  f >> num_countries;
1579 jag 67
  index.resize (num_countries);
964 jag 68
  for (int i = 0; i < num_countries; ++i) {
69
    f >> fname;
1579 jag 70
    index[i] = fname;
964 jag 71
  }
72
  sort (index.begin (), index.end());
73
}
74
 
75
 
76
void countries::setup () {
77
 
78
  plugin::setup ();
79
 
80
  load_index ();
81
 
1579 jag 82
  widget* _ctrls [] = {&ol_country, &ol_area,  &lf_search, &pt.step, &pt.start, &pt.end, &close};
83
  for (int i = 0; i < 7; ++i) {
84
    ctrls.push_back (_ctrls[i]);
85
  }
964 jag 86
 
87
  num_ctrls = ctrls.size ();
88
 
1579 jag 89
  //for (int i = 0; i < num_ctrls; ++i) ctrls[i]->set_moveable(1);
90
 
1120 jag 91
  lf_search.set_text ("Country?");
964 jag 92
  lf_search.set_listener (this);
1521 jag 93
  lf_search.fld.expr = 0;
94
 
964 jag 95
  ol_country.set_text ("Country = ");
96
  ol_country.set_listener (this);
97
  ol_country.set_click_repeat (1);
1521 jag 98
 
964 jag 99
  ol_area.set_listener (this);
100
  ol_area.set_click_repeat (1);
101
  ol_area.set_text ("Area = ");
102
 
1579 jag 103
  pt.start.set ("Start", 1, 1, MILLION, this, 0);
104
  pt.end.set ("End", 1, 1, MILLION, this, 0);
105
  pt.step.set ("Step", 1, 1, MILLION, this, 0);
964 jag 106
 
1579 jag 107
  close.set_text ("Close");
108
  close.set_listener (&cll);
109
 
964 jag 110
  widget_load ("d_countries", ctrls);
111
 
112
  load_params ();
113
  lf_search.fld.set_text (index[id]);
114
 
115
}
116
 
117
void countries::render () {
118
  if (p_cur_country) {
119
    points.clear ();
120
    area& a0 = p_cur_country->areas[area_id];
2107 jag 121
    int start = pt.start.value;
1579 jag 122
    float a0x = a0.x[start], a0y = a0.y[start];
964 jag 123
    point<float> pa0 (a0x, a0y);
124
    points.push_back (pa0);
2107 jag 125
    for (int i = start + 1, j = pt.end.value, di = pt.step.value; i < j; i += di) points.push_back (point<float>(a0.x[i], a0.y[i]));
1579 jag 126
    if (close.state || (points.size () == 1)) points.push_back (pa0);
127
    gen_pts ();
964 jag 128
    ss.str("");
129
    ss << p_cur_country->name;
130
  }
131
}
132
 
133
country* countries::load_country (const string& which) {
134
  country& c = the_countries [which];
135
  if (c.num_areas ==  0) {
136
    string fname (country_data_dir + which);
137
    ifstream f (fname.c_str(), ios::in);
138
    if (!f) {
139
      dlog << "couldnt load from : " << fname << endl;
140
      return 0;
141
    }
142
    c.name = which;
143
    string ignore;
144
    while (!f.eof()) {
145
      f >> ignore >> c.num_areas;
146
      for (int i = 0; i < c.num_areas; ++i) {
147
        c.areas.push_back (area());
148
        area& ai = c.areas[i];
149
        f >> ignore >> ai.num_vertices;
150
        float l, b, r, t; f >> ignore >> l >> b >> r >> t;
151
        ai.bbox (l, b, r, t);
1579 jag 152
 
1582 jag 153
        /*dlog << "name = " << c.name << " ratio = " << ai.bbox.width * 1.0 / ai.bbox.height << endl;
154
        float fac = ai.bbox.width * 1.0 / ai.bbox.height - 1.0;*/
155
 
1579 jag 156
        int& q = ai.num_vertices;
157
        int n1 = q + 1;
158
        ai.x.resize (n1);
159
        ai.y.resize (n1);
160
        for (int p = 0; p < q; ++p) f >> ai.x[p] >> ai.y[p];
161
        ai.x[q] = ai.x[0];
162
        ai.y[q] = ai.y[0];
163
        ++q;
964 jag 164
      }
165
    }
166
  }
167
  p_cur_country = &c;
168
  set_country (which);
169
  return &c;
170
}
171
 
172
void countries::picked (label& lbl, int dir) {
173
  if (&lbl == &ol_country.option) {
174
    id += dir;
175
    if (id < 0) id = num_countries - 1; else if (id >= num_countries) id = 0;
176
    string name (index[id]);
177
    load_country (name);
178
  } else if (&lbl == &ol_area.option) {
179
    if (p_cur_country) {
180
      area_id += dir;
181
      render_area ();
182
    }
183
  }
184
}
185
 
186
void countries::changed (field& f) {
187
  if (&f == &lf_search.fld) {
188
    string name (f.text);
1579 jag 189
    for (int i = 0, j = name.size (); i < j; ++i) if (name[i] == ' ') name[i]= '_';
964 jag 190
    int nid = find_id (name);
191
    if (nid == -1) {
1579 jag 192
      cons << RED << "Couldnt find " << name << eol;
964 jag 193
      if (name == "") f.set_text (index[id]);
194
    } else {
195
      id = nid;
196
      load_country (name);
197
    }
198
  } else {
199
    render ();
200
    if (cb_auto_apply.state) clicked (b_apply);
201
  }
202
}
203
 
204
void countries::render_area () {
205
  if (area_id < 0) area_id = p_cur_country->num_areas - 1; else if (area_id >= p_cur_country->num_areas) area_id = 0;
206
  stringstream ss; ss << "Area " << (area_id+1) << " of " << p_cur_country->num_areas;
207
  ol_area.set_text (ss.str());
1579 jag 208
 
209
  int n_1 = p_cur_country->areas[area_id].num_vertices - 1;
210
  pt.start.set_limits (0, n_1);
211
  pt.end.set_limits (0, n_1);
212
  pt.start.set_value (0);
213
  pt.end.set_value (n_1);
214
 
964 jag 215
  render ();
216
  if (cb_auto_apply.state) clicked (b_apply);
217
}
218
 
219
void countries::set_country (const string& name) {
220
  ol_country.set_text (name);
221
  lf_search.set_text (name);
222
  area_id = 0;
223
  render_area ();
224
}
225
 
226
int countries::find_id (const string& name) {
1579 jag 227
  for (int i = 0, j = index.size (); i < j; ++i) if (index[i] == name) return i;
964 jag 228
  return -1;
229
}
230
 
1579 jag 231
void countries::closer::changed (checkbutton& cb) {
232
  extern countries countries_;
233
  countries_.do_render ();
234
}
235
 
964 jag 236
void area::calc_bbox () {
237
  if (num_vertices) {
1579 jag 238
    float xmin = x[0], ymin = y[0];
239
    float xmax = xmin, ymax = ymin;
964 jag 240
    for (int i = 1, j = num_vertices; i < j; ++i) {
241
      float xi = x[i], yi = y[i];
242
      if (xi < xmin) xmin = xi; else if (xi > xmax) xmax = xi;
243
      if (yi < ymin) ymin = yi; else if (yi > ymax) ymax = yi;
244
    }
245
    bbox (xmin, ymin, xmax, ymax);
246
  }
247
}
248
 
249
void area::normalise () {
250
  float aspect_ratio = bbox.width * 1. / bbox.height;
251
  float xw = aspect_ratio * 2.0f, xwh = xw / 2.0f;
252
  for (int i = 0, j = num_vertices; i < j; ++i) {
253
    float xi = x[i], yi = y[i];
254
    float fx = (xi - bbox.left) * bbox.width_1;
255
    float fy = (yi - bbox.bottom) * bbox.height_1;
256
    float xj = -xwh + fx * xw;
257
    float yj = -1 + fy * 2.0f;
258
    x[i] = xj;
259
    y[i] = yj;
260
  }
261
  bbox (-xwh, -1.0f, xwh, 1.0f);
262
}