123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- /*!
- \file lib/imagery/iscatt_structs.c
- \brief Imagery library - functions for manipulation with structures used
- by wx.iscatt (wx Interactive Scatter Plot Tool)
- Copyright (C) 2013 by the GRASS Development Team
- This program is free software under the GNU General Public License
- (>=v2). Read the file COPYING that comes with GRASS for details.
- \author Stepan Turek <stepan.turek@seznam.cz> (GSoC 2013, Mentor: Martin Landa)
- */
- #include <math.h>
- #include <grass/imagery.h>
- #include <grass/gis.h>
- /*!
- \brief Compute band ids from scatter plot id.
- Scatter plot id describes which bands defines the scatter plot.
- Let say we have 3 bands, their ids are 0, 1 and 2.
- Scatter plot with id 0 consists of band 1 (b_1_id) 0 and band 2 (b_2_id) 1.
- All scatter plots:
- scatt_id b_1_id b_2_id
- 0 0 1
- 1 0 2
- 2 1 2
- \param scatt_id scatter plot id
- \param n_bands number of bands
- \param[out] b_1_id id of band1
- \param[out] b_2_id id of band2
- \return 0
- */
- int I_id_scatt_to_bands(const int scatt_id, const int n_bands, int *b_1_id,
- int *b_2_id)
- {
- int n_b1 = n_bands - 1;
- *b_1_id =
- (int)((2 * n_b1 + 1 -
- sqrt((double)((2 * n_b1 + 1) * (2 * n_b1 + 1) - 8 * scatt_id)))
- / 2);
- *b_2_id =
- scatt_id - ((*b_1_id) * (2 * n_b1 + 1) - (*b_1_id) * (*b_1_id)) / 2 +
- (*b_1_id) + 1;
- return 0;
- }
- /*!
- \brief Compute scatter plot id from band ids.
- See also I_id_scatt_to_bands
- \param b_1_id id of band1
- \param b_1_id id of band2
- \param n_bands number of bands
- \param[out] scatt_id scatter plot id
- \return 0
- */
- int I_bands_to_id_scatt(const int b_1_id, const int b_2_id, const int n_bands,
- int *scatt_id)
- {
- int n_b1 = n_bands - 1;
- *scatt_id =
- (b_1_id * (2 * n_b1 + 1) - b_1_id * b_1_id) / 2 + b_2_id - b_1_id - 1;
- return 0;
- }
- /*!
- \brief Initialize structure for storing scatter plots data.
- \param cats pointer to scCats struct
- \param n_bands number of bands
- \param type SC_SCATT_DATA - stores scatter plots
- \param type SC_SCATT_CONDITIONS - stores selected areas in scatter plots
- */
- void I_sc_init_cats(struct scCats *cats, int n_bands, int type)
- {
- int i_cat;
- cats->type = type;
- cats->n_cats = 100;
- cats->n_a_cats = 0;
- cats->n_bands = n_bands;
- cats->n_scatts = (n_bands - 1) * n_bands / 2;
- cats->cats_arr =
- (struct scScatts **)G_malloc(cats->n_cats *
- sizeof(struct scScatts *));
- G_zero(cats->cats_arr, cats->n_cats * sizeof(struct scScatts *));
- cats->cats_ids = (int *)G_malloc(cats->n_cats * sizeof(int));
- cats->cats_idxs = (int *)G_malloc(cats->n_cats * sizeof(int));
- for (i_cat = 0; i_cat < cats->n_cats; i_cat++)
- cats->cats_idxs[i_cat] = -1;
- return;
- }
- /*!
- \brief Free data of struct scCats, the structure itself remains allocated.
- \param cats pointer to existing scCats struct
- */
- void I_sc_free_cats(struct scCats *cats)
- {
- int i_cat;
- for (i_cat = 0; i_cat < cats->n_a_cats; i_cat++) {
- if (cats->cats_arr[i_cat]) {
- G_free(cats->cats_arr[i_cat]->scatt_idxs);
- G_free(cats->cats_arr[i_cat]->scatts_bands);
- G_free(cats->cats_arr[i_cat]->scatts_arr);
- G_free(cats->cats_arr[i_cat]);
- }
- }
- G_free(cats->cats_ids);
- G_free(cats->cats_idxs);
- G_free(cats->cats_arr);
- cats->n_cats = 0;
- cats->n_a_cats = 0;
- cats->n_bands = 0;
- cats->n_scatts = 0;
- cats->type = -1;
- return;
- }
- /*!
- \brief Add category.
- Category represents group of scatter plots.
- \param cats pointer to scCats struct
- \return assigned category id (starts with 0)
- \return -1 if maximum nuber of categories was reached
- */
- int I_sc_add_cat(struct scCats *cats)
- {
- int i_scatt, i_cat_id, cat_id;
- int n_a_cats = cats->n_a_cats;
- if (cats->n_a_cats >= cats->n_cats)
- return -1;
- for (i_cat_id = 0; i_cat_id < cats->n_cats; i_cat_id++)
- if (cats->cats_idxs[i_cat_id] < 0) {
- cat_id = i_cat_id;
- break;
- }
- cats->cats_ids[n_a_cats] = cat_id;
- cats->cats_idxs[cat_id] = n_a_cats;
- cats->cats_arr[n_a_cats] =
- (struct scScatts *)G_malloc(sizeof(struct scScatts));
- cats->cats_arr[n_a_cats]->scatts_arr =
- (struct scdScattData **)G_malloc(cats->n_scatts *
- sizeof(struct scdScattData *));
- G_zero((cats->cats_arr[n_a_cats]->scatts_arr),
- cats->n_scatts * sizeof(struct scdScattData *));
- cats->cats_arr[n_a_cats]->n_a_scatts = 0;
- cats->cats_arr[n_a_cats]->scatts_bands =
- (int *)G_malloc(cats->n_scatts * 2 * sizeof(int));
- cats->cats_arr[n_a_cats]->scatt_idxs =
- (int *)G_malloc(cats->n_scatts * sizeof(int));
- for (i_scatt = 0; i_scatt < cats->n_scatts; i_scatt++)
- cats->cats_arr[n_a_cats]->scatt_idxs[i_scatt] = -1;
- ++cats->n_a_cats;
- return cat_id;
- }
- /*!
- \brief Insert scatter plot data .
- Inserted scatt_data struct must have same type as
- cats struct (SC_SCATT_DATA or SC_SCATT_CONDITIONS).
- \param cats pointer to scCats struct
- \param scarr_data pointer to scdScattData struct
- \param cat_id id number of category
- \param scatt_id id number of scatter plot
- \return 0 on success
- \return -1 on failure
- */
- int I_sc_insert_scatt_data(struct scCats *cats,
- struct scdScattData *scatt_data, int cat_id,
- int scatt_id)
- {
- int band_1, band_2, cat_idx, n_a_scatts;
- struct scScatts *scatts;
- if (cat_id < 0 || cat_id >= cats->n_cats)
- return -1;
- cat_idx = cats->cats_idxs[cat_id];
- if (cat_idx < 0)
- return -1;
- if (scatt_id < 0 && scatt_id >= cats->n_scatts)
- return -1;
- scatts = cats->cats_arr[cat_idx];
- if (scatts->scatt_idxs[scatt_id] >= 0)
- return -1;
- if (!scatt_data->b_conds_arr && cats->type == SC_SCATT_CONDITIONS)
- return -1;
- if (!scatt_data->scatt_vals_arr && cats->type == SC_SCATT_DATA)
- return -1;
- n_a_scatts = scatts->n_a_scatts;
- scatts->scatt_idxs[scatt_id] = n_a_scatts;
- I_id_scatt_to_bands(scatt_id, cats->n_bands, &band_1, &band_2);
- scatts->scatts_bands[n_a_scatts * 2] = band_1;
- scatts->scatts_bands[n_a_scatts * 2 + 1] = band_2;
- scatts->scatts_arr[n_a_scatts] = scatt_data;
- ++scatts->n_a_scatts;
- return 0;
- }
- /*!
- \brief Insert scatter plot data.
- \param scatt_data pointer to existing struct scdScattData
- \param type SC_SCATT_DATA for scatter plots or
- SC_SCATT_CONDITIONS for selected areas in scatter plot
- \param n_vals number of data values
- \param data array of values (unsigned char for SC_SCATT_CONDITIONS,
- unsigned int for SC_SCATT_DATA)
- */
- void I_scd_init_scatt_data(struct scdScattData *scatt_data, int type,
- int n_vals, void *data)
- {
- scatt_data->n_vals = n_vals;
- if (type == SC_SCATT_DATA) {
- if (data)
- scatt_data->scatt_vals_arr = (unsigned int *)data;
- else {
- scatt_data->scatt_vals_arr =
- (unsigned int *)G_malloc(n_vals * sizeof(unsigned int));
- G_zero(scatt_data->scatt_vals_arr,
- n_vals * sizeof(unsigned int));
- }
- scatt_data->b_conds_arr = NULL;
- }
- else if (type == SC_SCATT_CONDITIONS) {
- if (data)
- scatt_data->b_conds_arr = (unsigned char *)data;
- else {
- scatt_data->b_conds_arr =
- (unsigned char *)G_malloc(n_vals * sizeof(unsigned char));
- G_zero(scatt_data->b_conds_arr,
- n_vals * sizeof(unsigned char));
- }
- scatt_data->scatt_vals_arr = NULL;
- }
- return;
- }
|