GRASS GIS 7 Programmer's Manual  7.5.svn(2018)-r73120
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
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 /*!
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  */
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:151
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:149
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:188
int n_cats
Definition: imagery.h:154
#define NULL
Definition: ccmath.h:32
int * scatts_bands
Definition: imagery.h:175
int n_scatts
Definition: imagery.h:157
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:159
int n_a_scatts
Definition: imagery.h:173
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:181
#define SC_SCATT_CONDITIONS
Definition: imagery.h:143
int n_bands
Definition: imagery.h:156
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:160
int * cats_idxs
Definition: imagery.h:162
unsigned int * scatt_vals_arr
Definition: imagery.h:193
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:142
struct scScatts ** cats_arr
Definition: imagery.h:165
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
Reads the categories file for map name in mapset and stores the categories in the pcats structure...
void G_zero(void *buf, int i)
Zero out a buffer, buf, of length i.
Definition: gis/zero.c:23
int * scatt_idxs
Definition: imagery.h:178
unsigned char * b_conds_arr
Definition: imagery.h:191