GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
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 */
41int 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 */
70int 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 */
89void 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 */
119void 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 */
155int 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) {
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 scatt_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 */
209 int cat_id, int scatt_id)
210{
211 int band_1, band_2, cat_idx, n_a_scatts;
212 struct scScatts *scatts;
213
215 return -1;
216
217 cat_idx = cats->cats_idxs[cat_id];
218 if (cat_idx < 0)
219 return -1;
220
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
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 */
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:147
#define G_malloc(n)
Definition defs/gis.h:139
#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 n_a_scatts
Definition imagery.h:165