-
-
Notifications
You must be signed in to change notification settings - Fork 288
/
iscatt_structs.c
290 lines (222 loc) · 7.22 KB
/
iscatt_structs.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
/*!
\file lib/imagery/iscatt_structs.c
\brief Imagery library - functions for manipulation with structures used
by wx.iscatt (wx Interactive Scatter Plot Tool)
Copyright (C) 2013 by the GRASS Development Team
This program is free software under the GNU General Public License
(>=v2). Read the file COPYING that comes with GRASS for details.
\author Stepan Turek <stepan.turek@seznam.cz> (GSoC 2013, Mentor: Martin Landa)
*/
#include <math.h>
#include <grass/imagery.h>
#include <grass/gis.h>
/*!
\brief Compute band ids from scatter plot id.
Scatter plot id describes which bands defines the scatter plot.
Let say we have 3 bands, their ids are 0, 1 and 2.
Scatter plot with id 0 consists of band 1 (b_1_id) 0 and band 2 (b_2_id) 1.
All scatter plots:
scatt_id b_1_id b_2_id
0 0 1
1 0 2
2 1 2
\param scatt_id scatter plot id
\param n_bands number of bands
\param[out] b_1_id id of band1
\param[out] b_2_id id of band2
\return 0
*/
int I_id_scatt_to_bands(const int scatt_id, const int n_bands, int *b_1_id,
int *b_2_id)
{
int n_b1 = n_bands - 1;
*b_1_id =
(int)((2 * n_b1 + 1 -
sqrt((double)((2 * n_b1 + 1) * (2 * n_b1 + 1) - 8 * scatt_id)))
/ 2);
*b_2_id =
scatt_id - ((*b_1_id) * (2 * n_b1 + 1) - (*b_1_id) * (*b_1_id)) / 2 +
(*b_1_id) + 1;
return 0;
}
/*!
\brief Compute scatter plot id from band ids.
See also I_id_scatt_to_bands
\param b_1_id id of band1
\param b_1_id id of band2
\param n_bands number of bands
\param[out] scatt_id scatter plot id
\return 0
*/
int I_bands_to_id_scatt(const int b_1_id, const int b_2_id, const int n_bands,
int *scatt_id)
{
int n_b1 = n_bands - 1;
*scatt_id =
(b_1_id * (2 * n_b1 + 1) - b_1_id * b_1_id) / 2 + b_2_id - b_1_id - 1;
return 0;
}
/*!
\brief Initialize structure for storing scatter plots data.
\param cats pointer to scCats struct
\param n_bands number of bands
\param type SC_SCATT_DATA - stores scatter plots
\param type SC_SCATT_CONDITIONS - stores selected areas in scatter plots
*/
void I_sc_init_cats(struct scCats *cats, int n_bands, int type)
{
int i_cat;
cats->type = type;
cats->n_cats = 100;
cats->n_a_cats = 0;
cats->n_bands = n_bands;
cats->n_scatts = (n_bands - 1) * n_bands / 2;
cats->cats_arr =
(struct scScatts **)G_malloc(cats->n_cats *
sizeof(struct scScatts *));
G_zero(cats->cats_arr, cats->n_cats * sizeof(struct scScatts *));
cats->cats_ids = (int *)G_malloc(cats->n_cats * sizeof(int));
cats->cats_idxs = (int *)G_malloc(cats->n_cats * sizeof(int));
for (i_cat = 0; i_cat < cats->n_cats; i_cat++)
cats->cats_idxs[i_cat] = -1;
return;
}
/*!
\brief Free data of struct scCats, the structure itself remains allocated.
\param cats pointer to existing scCats struct
*/
void I_sc_free_cats(struct scCats *cats)
{
int i_cat;
for (i_cat = 0; i_cat < cats->n_a_cats; i_cat++) {
if (cats->cats_arr[i_cat]) {
G_free(cats->cats_arr[i_cat]->scatt_idxs);
G_free(cats->cats_arr[i_cat]->scatts_bands);
G_free(cats->cats_arr[i_cat]->scatts_arr);
G_free(cats->cats_arr[i_cat]);
}
}
G_free(cats->cats_ids);
G_free(cats->cats_idxs);
G_free(cats->cats_arr);
cats->n_cats = 0;
cats->n_a_cats = 0;
cats->n_bands = 0;
cats->n_scatts = 0;
cats->type = -1;
return;
}
/*!
\brief Add category.
Category represents group of scatter plots.
\param cats pointer to scCats struct
\return assigned category id (starts with 0)
\return -1 if maximum nuber of categories was reached
*/
int I_sc_add_cat(struct scCats *cats)
{
int i_scatt, i_cat_id, cat_id;
int n_a_cats = cats->n_a_cats;
if (cats->n_a_cats >= cats->n_cats)
return -1;
for (i_cat_id = 0; i_cat_id < cats->n_cats; i_cat_id++)
if (cats->cats_idxs[i_cat_id] < 0) {
cat_id = i_cat_id;
break;
}
cats->cats_ids[n_a_cats] = cat_id;
cats->cats_idxs[cat_id] = n_a_cats;
cats->cats_arr[n_a_cats] =
(struct scScatts *)G_malloc(sizeof(struct scScatts));
cats->cats_arr[n_a_cats]->scatts_arr =
(struct scdScattData **)G_malloc(cats->n_scatts *
sizeof(struct scdScattData *));
G_zero((cats->cats_arr[n_a_cats]->scatts_arr),
cats->n_scatts * sizeof(struct scdScattData *));
cats->cats_arr[n_a_cats]->n_a_scatts = 0;
cats->cats_arr[n_a_cats]->scatts_bands =
(int *)G_malloc(cats->n_scatts * 2 * sizeof(int));
cats->cats_arr[n_a_cats]->scatt_idxs =
(int *)G_malloc(cats->n_scatts * sizeof(int));
for (i_scatt = 0; i_scatt < cats->n_scatts; i_scatt++)
cats->cats_arr[n_a_cats]->scatt_idxs[i_scatt] = -1;
++cats->n_a_cats;
return cat_id;
}
/*!
\brief Insert scatter plot data .
Inserted scatt_data struct must have same type as
cats struct (SC_SCATT_DATA or SC_SCATT_CONDITIONS).
\param cats pointer to scCats struct
\param scarr_data pointer to scdScattData struct
\param cat_id id number of category
\param scatt_id id number of scatter plot
\return 0 on success
\return -1 on failure
*/
int I_sc_insert_scatt_data(struct scCats *cats,
struct scdScattData *scatt_data, int cat_id,
int scatt_id)
{
int band_1, band_2, cat_idx, n_a_scatts;
struct scScatts *scatts;
if (cat_id < 0 || cat_id >= cats->n_cats)
return -1;
cat_idx = cats->cats_idxs[cat_id];
if (cat_idx < 0)
return -1;
if (scatt_id < 0 && scatt_id >= cats->n_scatts)
return -1;
scatts = cats->cats_arr[cat_idx];
if (scatts->scatt_idxs[scatt_id] >= 0)
return -1;
if (!scatt_data->b_conds_arr && cats->type == SC_SCATT_CONDITIONS)
return -1;
if (!scatt_data->scatt_vals_arr && cats->type == SC_SCATT_DATA)
return -1;
n_a_scatts = scatts->n_a_scatts;
scatts->scatt_idxs[scatt_id] = n_a_scatts;
I_id_scatt_to_bands(scatt_id, cats->n_bands, &band_1, &band_2);
scatts->scatts_bands[n_a_scatts * 2] = band_1;
scatts->scatts_bands[n_a_scatts * 2 + 1] = band_2;
scatts->scatts_arr[n_a_scatts] = scatt_data;
++scatts->n_a_scatts;
return 0;
}
/*!
\brief Insert scatter plot data.
\param scatt_data pointer to existing struct scdScattData
\param type SC_SCATT_DATA for scatter plots or
SC_SCATT_CONDITIONS for selected areas in scatter plot
\param n_vals number of data values
\param data array of values (unsigned char for SC_SCATT_CONDITIONS,
unsigned int for SC_SCATT_DATA)
*/
void I_scd_init_scatt_data(struct scdScattData *scatt_data, int type,
int n_vals, void *data)
{
scatt_data->n_vals = n_vals;
if (type == SC_SCATT_DATA) {
if (data)
scatt_data->scatt_vals_arr = (unsigned int *)data;
else {
scatt_data->scatt_vals_arr =
(unsigned int *)G_malloc(n_vals * sizeof(unsigned int));
G_zero(scatt_data->scatt_vals_arr,
n_vals * sizeof(unsigned int));
}
scatt_data->b_conds_arr = NULL;
}
else if (type == SC_SCATT_CONDITIONS) {
if (data)
scatt_data->b_conds_arr = (unsigned char *)data;
else {
scatt_data->b_conds_arr =
(unsigned char *)G_malloc(n_vals * sizeof(unsigned char));
G_zero(scatt_data->b_conds_arr,
n_vals * sizeof(unsigned char));
}
scatt_data->scatt_vals_arr = NULL;
}
return;
}