iscatt_structs.c 7.2 KB

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