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