GRASS GIS 8 Programmer's Manual  8.2.2dev(2023)-3d2c704037
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 Landa)
13  */
14 #include <math.h>
15 
16 #include <grass/imagery.h>
17 #include <grass/gis.h>
18 
19 /*!
20  \brief Compute band ids from scatter plot id.
21 
22  Scatter plot id describes which bands defines the scatter plot.
23 
24  Let say we have 3 bands, their ids are 0, 1 and 2.
25  Scatter plot with id 0 consists of band 1 (b_1_id) 0 and band 2 (b_2_id) 1.
26  All scatter plots:
27  scatt_id b_1_id b_2_id
28  0 0 1
29  1 0 2
30  2 1 2
31 
32  \param scatt_id scatter plot id
33  \param n_bands number of bands
34  \param[out] b_1_id id of band1
35  \param[out] b_2_id id of band2
36 
37  \return 0
38  */
39 int I_id_scatt_to_bands(const int scatt_id, const int n_bands, int *b_1_id,
40  int *b_2_id)
41 {
42  int n_b1 = n_bands - 1;
43 
44  *b_1_id =
45  (int)((2 * n_b1 + 1 -
46  sqrt((double)((2 * n_b1 + 1) * (2 * n_b1 + 1) - 8 * scatt_id)))
47  / 2);
48 
49  *b_2_id =
50  scatt_id - ((*b_1_id) * (2 * n_b1 + 1) - (*b_1_id) * (*b_1_id)) / 2 +
51  (*b_1_id) + 1;
52 
53  return 0;
54 }
55 
56 
57 /*!
58  \brief Compute scatter plot id from band ids.
59 
60  See also I_id_scatt_to_bands
61 
62  \param b_1_id id of band1
63  \param b_1_id id of band2
64  \param n_bands number of bands
65  \param[out] scatt_id scatter plot id
66 
67  \return 0
68  */
69 int I_bands_to_id_scatt(const int b_1_id, const int b_2_id, const int n_bands,
70  int *scatt_id)
71 {
72  int n_b1 = n_bands - 1;
73 
74  *scatt_id =
75  (b_1_id * (2 * n_b1 + 1) - b_1_id * b_1_id) / 2 + b_2_id - b_1_id - 1;
76 
77  return 0;
78 }
79 
80 /*!
81  \brief Initialize structure for storing scatter plots data.
82 
83  \param cats pointer to scCats struct
84  \param n_bands number of bands
85  \param type SC_SCATT_DATA - stores scatter plots
86  \param type SC_SCATT_CONDITIONS - stores selected areas in scatter plots
87  */
88 void I_sc_init_cats(struct scCats *cats, int n_bands, int type)
89 {
90  int i_cat;
91 
92  cats->type = type;
93 
94  cats->n_cats = 100;
95  cats->n_a_cats = 0;
96 
97  cats->n_bands = n_bands;
98  cats->n_scatts = (n_bands - 1) * n_bands / 2;
99 
100  cats->cats_arr =
101  (struct scScatts **)G_malloc(cats->n_cats *
102  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 nuber of categories was reached
154  */
155 int I_sc_add_cat(struct scCats *cats)
156 {
157  int i_scatt, i_cat_id, cat_id;
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 =
176  (struct scdScattData **)G_malloc(cats->n_scatts *
177  sizeof(struct scdScattData *));
178  G_zero((cats->cats_arr[n_a_cats]->scatts_arr),
179  cats->n_scatts * sizeof(struct scdScattData *));
180 
181  cats->cats_arr[n_a_cats]->n_a_scatts = 0;
182 
183  cats->cats_arr[n_a_cats]->scatts_bands =
184  (int *)G_malloc(cats->n_scatts * 2 * sizeof(int));
185 
186  cats->cats_arr[n_a_cats]->scatt_idxs =
187  (int *)G_malloc(cats->n_scatts * sizeof(int));
188  for (i_scatt = 0; i_scatt < cats->n_scatts; i_scatt++)
189  cats->cats_arr[n_a_cats]->scatt_idxs[i_scatt] = -1;
190 
191  ++cats->n_a_cats;
192 
193  return cat_id;
194 }
195 
196 /*!
197  \brief Insert scatter plot data .
198  Inserted scatt_data struct must have same type as
199  cats struct (SC_SCATT_DATA or SC_SCATT_CONDITIONS).
200 
201  \param cats pointer to scCats struct
202  \param scarr_data pointer to scdScattData struct
203  \param cat_id id number of category
204  \param scatt_id id number of scatter plot
205 
206  \return 0 on success
207  \return -1 on failure
208  */
210  struct scdScattData *scatt_data, int cat_id,
211  int scatt_id)
212 {
213  int band_1, band_2, cat_idx, n_a_scatts;
214  struct scScatts *scatts;
215 
216  if (cat_id < 0 || cat_id >= cats->n_cats)
217  return -1;
218 
219  cat_idx = cats->cats_idxs[cat_id];
220  if (cat_idx < 0)
221  return -1;
222 
223  if (scatt_id < 0 && scatt_id >= cats->n_scatts)
224  return -1;
225 
226  scatts = cats->cats_arr[cat_idx];
227  if (scatts->scatt_idxs[scatt_id] >= 0)
228  return -1;
229 
230  if (!scatt_data->b_conds_arr && cats->type == SC_SCATT_CONDITIONS)
231  return -1;
232 
233  if (!scatt_data->scatt_vals_arr && cats->type == SC_SCATT_DATA)
234  return -1;
235 
236  n_a_scatts = scatts->n_a_scatts;
237 
238  scatts->scatt_idxs[scatt_id] = n_a_scatts;
239 
240  I_id_scatt_to_bands(scatt_id, cats->n_bands, &band_1, &band_2);
241 
242  scatts->scatts_bands[n_a_scatts * 2] = band_1;
243  scatts->scatts_bands[n_a_scatts * 2 + 1] = band_2;
244 
245  scatts->scatts_arr[n_a_scatts] = scatt_data;
246  ++scatts->n_a_scatts;
247 
248  return 0;
249 }
250 
251 /*!
252  \brief Insert scatter plot data.
253 
254  \param scatt_data pointer to existing struct scdScattData
255  \param type SC_SCATT_DATA for scatter plots or
256  SC_SCATT_CONDITIONS for selected areas in scatter plot
257  \param n_vals number of data values
258  \param data array of values (unsigned char for SC_SCATT_CONDITIONS,
259  unsigned int for SC_SCATT_DATA)
260  */
261 void I_scd_init_scatt_data(struct scdScattData *scatt_data, int type,
262  int n_vals, void *data)
263 {
264  scatt_data->n_vals = n_vals;
265 
266  if (type == SC_SCATT_DATA) {
267  if (data)
268  scatt_data->scatt_vals_arr = (unsigned int *)data;
269  else {
270  scatt_data->scatt_vals_arr =
271  (unsigned int *)G_malloc(n_vals * sizeof(unsigned int));
272  G_zero(scatt_data->scatt_vals_arr,
273  n_vals * sizeof(unsigned int));
274  }
275  scatt_data->b_conds_arr = NULL;
276  }
277  else if (type == SC_SCATT_CONDITIONS) {
278  if (data)
279  scatt_data->b_conds_arr = (unsigned char *)data;
280  else {
281  scatt_data->b_conds_arr =
282  (unsigned char *)G_malloc(n_vals * sizeof(unsigned char));
283  G_zero(scatt_data->b_conds_arr,
284  n_vals * sizeof(unsigned char));
285  }
286  scatt_data->scatt_vals_arr = NULL;
287  }
288 
289  return;
290 }
int type
Definition: imagery.h:153
#define G_malloc(n)
Definition: defs/gis.h:112
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 n_vals
Definition: imagery.h:190
int n_cats
Definition: imagery.h:156
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:149
#define NULL
Definition: ccmath.h:32
int * scatts_bands
Definition: imagery.h:177
int n_scatts
Definition: imagery.h:159
void I_sc_free_cats(struct scCats *cats)
Free data of struct scCats, the structure itself remains allocated.
int n_a_cats
Definition: imagery.h:161
int n_a_scatts
Definition: imagery.h:175
void I_scd_init_scatt_data(struct scdScattData *scatt_data, int type, int n_vals, void *data)
Insert scatter plot data.
struct scdScattData ** scatts_arr
Definition: imagery.h:183
#define SC_SCATT_CONDITIONS
Definition: imagery.h:145
int n_bands
Definition: imagery.h:158
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.
int * cats_ids
Definition: imagery.h:162
int * cats_idxs
Definition: imagery.h:164
unsigned int * scatt_vals_arr
Definition: imagery.h:195
void I_sc_init_cats(struct scCats *cats, int n_bands, int type)
Initialize structure for storing scatter plots data.
#define SC_SCATT_DATA
Definition: imagery.h:144
void G_zero(void *, int)
Zero out a buffer, buf, of length i.
Definition: gis/zero.c:23
struct scScatts ** cats_arr
Definition: imagery.h:167
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 * scatt_idxs
Definition: imagery.h:180
unsigned char * b_conds_arr
Definition: imagery.h:193
int I_sc_add_cat(struct scCats *cats)
Add category.