[GRASS-SVN] r57761 - sandbox/turek/scatter_plot
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Sep 20 05:39:40 PDT 2013
Author: turek
Date: 2013-09-20 05:39:39 -0700 (Fri, 20 Sep 2013)
New Revision: 57761
Modified:
sandbox/turek/scatter_plot/testing_patch.diff
Log:
scatter plot: signaling busy state and show coorinates of cursor in plot heading
Modified: sandbox/turek/scatter_plot/testing_patch.diff
===================================================================
--- sandbox/turek/scatter_plot/testing_patch.diff 2013-09-20 10:39:00 UTC (rev 57760)
+++ sandbox/turek/scatter_plot/testing_patch.diff 2013-09-20 12:39:39 UTC (rev 57761)
@@ -1,413 +1,3 @@
-Index: lib/imagery/scatt_sccats.c
-===================================================================
---- lib/imagery/scatt_sccats.c (revision 0)
-+++ lib/imagery/scatt_sccats.c (working copy)
-@@ -0,0 +1,405 @@
-+/*!
-+ \file lib/imagery/scatt_cat_rast.c
-+
-+ \brief Imagery library - functions for manipulation with scatter plot structs.
-+
-+ 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 at seznam.cz> (Mentor: Martin Landa)
-+ */
-+
-+#include <grass/raster.h>
-+#include <grass/imagery.h>
-+#include <grass/gis.h>
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <math.h>
-+#include <string.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 n_bands number of bands
-+ \param b_1_id id of band1
-+ \param b_1_id id of band2
-+ \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 *));
-+ memset(cats->cats_arr, 0, 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 alocated.
-+
-+ \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;
-+}
-+
-+#if 0
-+void I_sc_get_active_categories(int * a_cats_ids, int * n_a_cats, struct scCats * cats)
-+{
-+ a_cats_ids = cats->cats_ids;
-+ * n_a_cats = cats->n_a_cats;
-+}
-+#endif
-+
-+/*!
-+ \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 *));
-+ memset((cats->cats_arr[n_a_cats]->scatts_arr), 0, 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;
-+}
-+
-+#if 0
-+int I_sc_delete_cat(struct scCats * cats, int cat_id)
-+{
-+ int cat_idx, i_cat;
-+
-+ if(cat_id < 0 || cat_id >= cats->n_cats)
-+ return -1;
-+
-+ cat_idx = cats->cats_idxs[cat_id];
-+ if(cat_idx < 0)
-+ return -1;
-+
-+ G_free(cats->cats_arr[cat_idx]->scatt_idxs);
-+ G_free(cats->cats_arr[cat_idx]->scatts_bands);
-+ G_free(cats->cats_arr[cat_idx]->scatts_arr);
-+ G_free(cats->cats_arr[cat_idx]);
-+
-+ for(i_cat = cat_idx; i_cat < cats->n_a_cats - 1; i_cat++)
-+ {
-+ cats->cats_arr[i_cat] = cats->cats_arr[i_cat + 1];
-+ cats->cats_ids[i_cat] = cats->cats_ids[i_cat + 1];
-+ }
-+ cats->cats_idxs[cat_id] = -1;
-+
-+ --cats->n_a_cats;
-+
-+ return 0;
-+}
-+#endif
-+
-+/*!
-+ \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 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;
-+}
-+
-+#if 0
-+int I_sc_remove_scatt_data(struct scCats * cats, struct scdScattData * scatt_data, int cat_id, int scatt_id)
-+{
-+ int cat_idx, scatt_idx, n_init_scatts, i_scatt;
-+ 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;
-+
-+ scatt_data = scatts->scatts_arr[scatt_idx];
-+
-+ for(i_scatt = scatt_idx; i_scatt < scatts->n_a_scatts - 1; i_scatt++)
-+ {
-+ scatts->scatts_arr[i_scatt] = scatts->scatts_arr[i_scatt + 1];
-+ scatts->scatts_bands[i_scatt * 2] = scatts->scatts_bands[(i_scatt + 1)* 2];
-+ scatts->scatts_bands[i_scatt * 2 + 1] = scatts->scatts_bands[(i_scatt + 1) * 2 + 1];
-+ }
-+ scatts->scatts_arr[scatts->n_a_scatts] = NULL;
-+
-+ scatts->scatt_idxs[scatt_id] = -1;
-+
-+ scatt_data = scatts->scatts_arr[scatt_id];
-+ scatts->n_a_scatts--;
-+
-+ return 0;
-+}
-+
-+int I_sc_set_value(struct scCats * cats, int cat_id, int scatt_id, int value_idx, int value)
-+{
-+ int n_a_scatts = cats->cats_arr[cat_id]->n_a_scatts;
-+ int cat_idx, scatt_idx, ret;
-+
-+ cat_idx = cats->cats_idxs[cat_id];
-+ if(cat_idx < 0)
-+ return -1;
-+
-+ if(cats->cats_arr[cat_idx]->scatt_idxs[scatt_id] < 0)
-+ return -1;
-+
-+ cat_idx = cats->cats_idxs[cat_id];
-+ scatt_idx = cats->cats_arr[cat_idx]->scatt_idxs[scatt_id];
-+
-+ I_scd_set_value(cats->cats_arr[cat_idx]->scatts_arr[scatt_idx], value_idx, value);
-+
-+ return 0;
-+}
-+#endif
-+
-+/*!
-+ \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));
-+ memset(scatt_data->scatt_vals_arr, 0, 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));
-+ memset(scatt_data->b_conds_arr, 0, n_vals * sizeof(unsigned char));
-+ }
-+ scatt_data->scatt_vals_arr = NULL;
-+ }
-+
-+ return;
-+}
-+
-+
-+#if 0
-+void I_scd_get_range_min_max(struct scdScattData * scatt_data, CELL * band_1_min, CELL * band_1_max, CELL * band_2_min, CELL * band_2_max)
-+{
-+
-+ Rast_get_range_min_max(&(scatt_data->band_1_range), band_1_min, band_2_min);
-+ Rast_get_range_min_max(&(scatt_data->band_2_range), band_2_min, band_2_max);
-+
-+ return;
-+}
-+s
-+void * I_scd_get_data_ptr(struct scdScattData * scatt_data)
-+{
-+ if(!scatt_data->b_conds_arr)
-+ return scatt_data->b_conds_arr;
-+ else if(!scatt_data->scatt_vals_arr)
-+ return scatt_data->scatt_vals_arr;
-+
-+ return NULL;
-+}
-+
-+int I_scd_set_value(struct scdScattData * scatt_data, unsigned int val_idx, unsigned int val)
-+{
-+ if(val_idx < 0 && val_idx > scatt_data->n_vals)
-+ return -1;
-+
-+ if(scatt_data->b_conds_arr)
-+ scatt_data->b_conds_arr[val_idx] = val;
-+ else if(scatt_data->scatt_vals_arr)
-+ scatt_data->scatt_vals_arr[val_idx] = val;
-+ else
-+ return -1;
-+
-+ return 0;
-+}
-+#endif
Index: lib/imagery/scatt.c
===================================================================
--- lib/imagery/scatt.c (revision 0)
@@ -1284,9 +874,419 @@
+ G_free(perimeter.points);
+ return 0;
+}
+Index: lib/imagery/scatt_sccats.c
+===================================================================
+--- lib/imagery/scatt_sccats.c (revision 0)
++++ lib/imagery/scatt_sccats.c (working copy)
+@@ -0,0 +1,405 @@
++/*!
++ \file lib/imagery/scatt_cat_rast.c
++
++ \brief Imagery library - functions for manipulation with scatter plot structs.
++
++ 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 at seznam.cz> (Mentor: Martin Landa)
++ */
++
++#include <grass/raster.h>
++#include <grass/imagery.h>
++#include <grass/gis.h>
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <math.h>
++#include <string.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 n_bands number of bands
++ \param b_1_id id of band1
++ \param b_1_id id of band2
++ \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 *));
++ memset(cats->cats_arr, 0, 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 alocated.
++
++ \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;
++}
++
++#if 0
++void I_sc_get_active_categories(int * a_cats_ids, int * n_a_cats, struct scCats * cats)
++{
++ a_cats_ids = cats->cats_ids;
++ * n_a_cats = cats->n_a_cats;
++}
++#endif
++
++/*!
++ \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 *));
++ memset((cats->cats_arr[n_a_cats]->scatts_arr), 0, 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;
++}
++
++#if 0
++int I_sc_delete_cat(struct scCats * cats, int cat_id)
++{
++ int cat_idx, i_cat;
++
++ if(cat_id < 0 || cat_id >= cats->n_cats)
++ return -1;
++
++ cat_idx = cats->cats_idxs[cat_id];
++ if(cat_idx < 0)
++ return -1;
++
++ G_free(cats->cats_arr[cat_idx]->scatt_idxs);
++ G_free(cats->cats_arr[cat_idx]->scatts_bands);
++ G_free(cats->cats_arr[cat_idx]->scatts_arr);
++ G_free(cats->cats_arr[cat_idx]);
++
++ for(i_cat = cat_idx; i_cat < cats->n_a_cats - 1; i_cat++)
++ {
++ cats->cats_arr[i_cat] = cats->cats_arr[i_cat + 1];
++ cats->cats_ids[i_cat] = cats->cats_ids[i_cat + 1];
++ }
++ cats->cats_idxs[cat_id] = -1;
++
++ --cats->n_a_cats;
++
++ return 0;
++}
++#endif
++
++/*!
++ \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 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;
++}
++
++#if 0
++int I_sc_remove_scatt_data(struct scCats * cats, struct scdScattData * scatt_data, int cat_id, int scatt_id)
++{
++ int cat_idx, scatt_idx, n_init_scatts, i_scatt;
++ 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;
++
++ scatt_data = scatts->scatts_arr[scatt_idx];
++
++ for(i_scatt = scatt_idx; i_scatt < scatts->n_a_scatts - 1; i_scatt++)
++ {
++ scatts->scatts_arr[i_scatt] = scatts->scatts_arr[i_scatt + 1];
++ scatts->scatts_bands[i_scatt * 2] = scatts->scatts_bands[(i_scatt + 1)* 2];
++ scatts->scatts_bands[i_scatt * 2 + 1] = scatts->scatts_bands[(i_scatt + 1) * 2 + 1];
++ }
++ scatts->scatts_arr[scatts->n_a_scatts] = NULL;
++
++ scatts->scatt_idxs[scatt_id] = -1;
++
++ scatt_data = scatts->scatts_arr[scatt_id];
++ scatts->n_a_scatts--;
++
++ return 0;
++}
++
++int I_sc_set_value(struct scCats * cats, int cat_id, int scatt_id, int value_idx, int value)
++{
++ int n_a_scatts = cats->cats_arr[cat_id]->n_a_scatts;
++ int cat_idx, scatt_idx, ret;
++
++ cat_idx = cats->cats_idxs[cat_id];
++ if(cat_idx < 0)
++ return -1;
++
++ if(cats->cats_arr[cat_idx]->scatt_idxs[scatt_id] < 0)
++ return -1;
++
++ cat_idx = cats->cats_idxs[cat_id];
++ scatt_idx = cats->cats_arr[cat_idx]->scatt_idxs[scatt_id];
++
++ I_scd_set_value(cats->cats_arr[cat_idx]->scatts_arr[scatt_idx], value_idx, value);
++
++ return 0;
++}
++#endif
++
++/*!
++ \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));
++ memset(scatt_data->scatt_vals_arr, 0, 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));
++ memset(scatt_data->b_conds_arr, 0, n_vals * sizeof(unsigned char));
++ }
++ scatt_data->scatt_vals_arr = NULL;
++ }
++
++ return;
++}
++
++
++#if 0
++void I_scd_get_range_min_max(struct scdScattData * scatt_data, CELL * band_1_min, CELL * band_1_max, CELL * band_2_min, CELL * band_2_max)
++{
++
++ Rast_get_range_min_max(&(scatt_data->band_1_range), band_1_min, band_2_min);
++ Rast_get_range_min_max(&(scatt_data->band_2_range), band_2_min, band_2_max);
++
++ return;
++}
++s
++void * I_scd_get_data_ptr(struct scdScattData * scatt_data)
++{
++ if(!scatt_data->b_conds_arr)
++ return scatt_data->b_conds_arr;
++ else if(!scatt_data->scatt_vals_arr)
++ return scatt_data->scatt_vals_arr;
++
++ return NULL;
++}
++
++int I_scd_set_value(struct scdScattData * scatt_data, unsigned int val_idx, unsigned int val)
++{
++ if(val_idx < 0 && val_idx > scatt_data->n_vals)
++ return -1;
++
++ if(scatt_data->b_conds_arr)
++ scatt_data->b_conds_arr[val_idx] = val;
++ else if(scatt_data->scatt_vals_arr)
++ scatt_data->scatt_vals_arr[val_idx] = val;
++ else
++ return -1;
++
++ return 0;
++}
++#endif
Index: include/defs/vedit.h
===================================================================
---- include/defs/vedit.h (revision 57747)
+--- include/defs/vedit.h (revision 57760)
+++ include/defs/vedit.h (working copy)
@@ -33,6 +33,8 @@
int Vedit_merge_lines(struct Map_info *, struct ilist *);
@@ -1299,7 +1299,7 @@
Index: include/defs/imagery.h
===================================================================
---- include/defs/imagery.h (revision 57747)
+--- include/defs/imagery.h (revision 57760)
+++ include/defs/imagery.h (working copy)
@@ -111,6 +111,28 @@
FILE *I_fopen_subgroup_ref_new(const char *, const char *);
@@ -1332,7 +1332,7 @@
int I_new_signature(struct Signature *);
Index: include/imagery.h
===================================================================
---- include/imagery.h (revision 57747)
+--- include/imagery.h (revision 57760)
+++ include/imagery.h (working copy)
@@ -135,6 +135,56 @@
@@ -1391,24 +1391,9 @@
#define SIGNATURE_TYPE_MIXED 1
#define GROUPFILE "CURGROUP"
-Index: gui/icons/grass/polygon.png
-===================================================================
-Cannot display: file marked as a binary type.
-svn:mime-type = application/octet-stream
-Index: gui/icons/grass/polygon.png
-===================================================================
---- gui/icons/grass/polygon.png (revision 57747)
-+++ gui/icons/grass/polygon.png (working copy)
-
-Property changes on: gui/icons/grass/polygon.png
-___________________________________________________________________
-Added: svn:mime-type
-## -0,0 +1 ##
-+application/octet-stream
-\ No newline at end of property
Index: gui/wxpython/vdigit/wxdigit.py
===================================================================
---- gui/wxpython/vdigit/wxdigit.py (revision 57747)
+--- gui/wxpython/vdigit/wxdigit.py (revision 57760)
+++ gui/wxpython/vdigit/wxdigit.py (working copy)
@@ -17,7 +17,7 @@
(and NumPy would be an excellent candidate for acceleration via
@@ -1438,7 +1423,7 @@
+
+ # signals which describes features changes during digitization,
+ # activate them using EmitSignals method
-+ #TODO signal for errors?
++ #TODO handle errors?
+ self.featureAdded = Signal('IVDigit.featureAdded')
+ self.areasDeleted = Signal('IVDigit.areasDeleted')
+ self.vertexMoved = Signal('IVDigit.vertexMoved')
@@ -1473,7 +1458,7 @@
layer = self._getNewFeaturesLayer()
cat = self._getNewFeaturesCat()
-@@ -419,10 +439,14 @@
+@@ -419,10 +439,15 @@
return (-1, None)
self.toolbar.EnableUndo()
@@ -1485,14 +1470,15 @@
+ ret = self._addFeature(vtype, points, layer, cat,
+ self._getSnapMode(), self._display.GetThreshold())
+ if ret[0] > -1 and self.emit_signals:
-+ self.featureAdded.emit(new_bboxs = [self._createBbox(points)], new_areas_cats = [[{layer : [cat]}, None]])
++ self.featureAdded.emit(new_bboxs=[self._createBbox(points)],
++ new_areas_cats=[[{layer : [cat]}, None]])
+
+ return ret
+
def DeleteSelectedLines(self):
"""!Delete selected features
-@@ -434,16 +458,27 @@
+@@ -434,16 +459,27 @@
# collect categories for deleting if requested
deleteRec = UserSettings.Get(group = 'vdigit', key = 'delRecord', subkey = 'enabled')
catDict = dict()
@@ -1525,19 +1511,20 @@
poList = self._display.GetSelectedIList()
nlines = Vedit_delete_lines(self.poMapInfo, poList)
-@@ -456,7 +491,10 @@
+@@ -456,7 +492,11 @@
self._deleteRecords(catDict)
self._addChangeset()
self.toolbar.EnableUndo()
-
+
+ if self.emit_signals:
-+ self.featuresDeleted.emit(old_bboxs = old_bboxs, old_areas_cats = old_areas_cats)
++ self.featuresDeleted.emit(old_bboxs=old_bboxs,
++ old_areas_cats=old_areas_cats)
+
return nlines
def _deleteRecords(self, cats):
-@@ -512,22 +550,173 @@
+@@ -512,22 +552,173 @@
@return number of deleted
"""
@@ -1570,7 +1557,8 @@
self._addChangeset()
self.toolbar.EnableUndo()
+ if self.emit_signals:
-+ self.areasDeleted.emit(old_bboxs = old_bboxs, old_areas_cats = old_areas_cats)
++ self.areasDeleted.emit(old_bboxs=old_bboxs,
++ old_areas_cats=old_areas_cats)
+
+ return nareas
+
@@ -1578,7 +1566,7 @@
+ ltype = Vect_read_line(self.poMapInfo, None, None, ln_id)
+
+ if ltype == GV_CENTROID:
-+ #TODO centroid opttimization, can be adited also its area -> it will appear two times in new_ lists
++ #TODO centroid opttimization, can be edited also its area -> it will appear two times in new_ lists
+ return self._getCentroidAreaBboxCats(ln_id)
+ else:
+ return [self._getBbox(ln_id)], [self._getLineAreasCategories(ln_id)]
@@ -1595,7 +1583,6 @@
+ return None
+
+ def _getaAreaBboxCats(self, area):
-+
+ po_b_list = Vect_new_list()
+ Vect_get_area_boundaries(self.poMapInfo, area, po_b_list);
+ b_list = po_b_list.contents
@@ -1713,7 +1700,7 @@
def MoveSelectedLines(self, move):
"""!Move selected features
-@@ -536,16 +725,45 @@
+@@ -536,16 +727,45 @@
if not self._checkMap():
return -1
@@ -1760,22 +1747,22 @@
if nlines > 0 and self._settings['breakLines']:
for i in range(1, nlines):
self._breakLineAtIntersection(nlines + i, None, changeset)
-@@ -553,7 +771,13 @@
+@@ -553,7 +773,13 @@
if nlines > 0:
self._addChangeset()
self.toolbar.EnableUndo()
-
+
+ if self.emit_signals:
-+ self.featuresMoved.emit(new_bboxs = new_bboxs,
-+ old_bboxs = old_bboxs,
-+ old_areas_cats = old_areas_cats,
-+ new_areas_cats = new_areas_cats)
++ self.featuresMoved.emit(new_bboxs=new_bboxs,
++ old_bboxs=old_bboxs,
++ old_areas_cats=old_areas_cats,
++ new_areas_cats=new_areas_cats)
+
return nlines
def MoveSelectedVertex(self, point, move):
-@@ -571,12 +795,21 @@
+@@ -571,12 +797,21 @@
if len(self._display.selected['ids']) != 1:
return -1
@@ -1801,7 +1788,7 @@
moved = Vedit_move_vertex(self.poMapInfo, self.popoBgMapInfo, int(self.poBgMapInfo is not None),
poList, self.poPoints,
self._display.GetThreshold(type = 'selectThresh'),
-@@ -584,7 +817,17 @@
+@@ -584,7 +819,17 @@
move[0], move[1], 0.0,
1, self._getSnapMode())
Vect_destroy_list(poList)
@@ -1820,22 +1807,22 @@
if moved > 0 and self._settings['breakLines']:
self._breakLineAtIntersection(Vect_get_num_lines(self.poMapInfo),
None)
-@@ -592,7 +835,13 @@
+@@ -592,7 +837,13 @@
if moved > 0:
self._addChangeset()
self.toolbar.EnableUndo()
-
+
+ if self.emit_signals:
-+ self.vertexMoved.emit(new_bboxs = new_bboxs,
-+ new_areas_cats = new_areas_cats,
-+ old_areas_cats = old_areas_cats,
-+ old_bboxs = old_bboxs)
++ self.vertexMoved.emit(new_bboxs=new_bboxs,
++ new_areas_cats=new_areas_cats,
++ old_areas_cats=old_areas_cats,
++ old_bboxs=old_bboxs)
+
return moved
def AddVertex(self, coords):
-@@ -681,6 +930,10 @@
+@@ -681,6 +932,10 @@
self._error.ReadLine(line)
return -1
@@ -1846,7 +1833,7 @@
# build feature geometry
Vect_reset_line(self.poPoints)
for p in coords:
-@@ -696,6 +949,9 @@
+@@ -696,6 +951,9 @@
newline = Vect_rewrite_line(self.poMapInfo, line, ltype,
self.poPoints, self.poCats)
@@ -1856,22 +1843,22 @@
if newline > 0 and self._settings['breakLines']:
self._breakLineAtIntersection(newline, None)
-@@ -703,7 +959,13 @@
+@@ -703,7 +961,13 @@
if newline > 0:
self._addChangeset()
self.toolbar.EnableUndo()
-
+
+ if self.emit_signals:
-+ self.lineEdited.emit(old_bboxs = old_bboxs,
-+ old_areas_cats = old_areas_cats,
-+ new_bboxs = new_bboxs,
-+ new_areas_cats = new_areas_cats)
++ self.lineEdited.emit(old_bboxs=old_bboxs,
++ old_areas_cats=old_areas_cats,
++ new_bboxs=new_bboxs,
++ new_areas_cats=new_areas_cats)
+
return newline
def FlipLine(self):
-@@ -1514,6 +1776,16 @@
+@@ -1514,6 +1778,16 @@
return 0
poList = self._display.GetSelectedIList()
@@ -1888,7 +1875,7 @@
Vect_reset_line(self.poPoints)
Vect_append_point(self.poPoints, coords[0], coords[1], 0.0)
-@@ -1525,15 +1797,35 @@
+@@ -1525,15 +1799,35 @@
else:
ret = Vedit_remove_vertex(self.poMapInfo, poList,
self.poPoints, thresh)
@@ -1916,19 +1903,19 @@
+
+ if ret > 0 and self.emit_signals:
+ if add:
-+ self.vertexAdded.emit(old_bboxs = old_bboxs, new_bboxs = new_bboxs)
++ self.vertexAdded.emit(old_bboxs=old_bboxs, new_bboxs=new_bboxs)
+ else:
-+ self.vertexRemoved.emit(old_bboxs = old_bboxs,
-+ new_bboxs = new_bboxs,
-+ old_areas_cats = old_areas_cats,
-+ new_areas_cats = new_areas_cats)
++ self.vertexRemoved.emit(old_bboxs=old_bboxs,
++ new_bboxs=new_bboxs,
++ old_areas_cats=old_areas_cats,
++ new_areas_cats=new_areas_cats)
+
return 1
def GetLineCats(self, line):
Index: gui/wxpython/vdigit/toolbars.py
===================================================================
---- gui/wxpython/vdigit/toolbars.py (revision 57747)
+--- gui/wxpython/vdigit/toolbars.py (revision 57760)
+++ gui/wxpython/vdigit/toolbars.py (working copy)
@@ -17,6 +17,7 @@
import wx
@@ -1955,600 +1942,9 @@
return True
def StopEditing(self):
-Index: gui/wxpython/vnet/toolbars.py
-===================================================================
---- gui/wxpython/vnet/toolbars.py (revision 57747)
-+++ gui/wxpython/vnet/toolbars.py (working copy)
-@@ -19,9 +19,9 @@
-
- import wx
-
--from icon import MetaIcon
-+from icons.icon import MetaIcon
- from gui_core.toolbars import BaseToolbar, BaseIcons
--from core.gcmd import RunCommand
-+from core.gcmd import RunCommand
- from core.utils import _
-
- class PointListToolbar(BaseToolbar):
-Index: gui/wxpython/vnet/dialogs.py
-===================================================================
---- gui/wxpython/vnet/dialogs.py (revision 57747)
-+++ gui/wxpython/vnet/dialogs.py (working copy)
-@@ -1218,7 +1218,7 @@
- pos = (row, 1))
-
- row += 1
-- gridSizer.Add(item = self.settings["invert_colors"], flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
-+ gridSizer.Add(item=self.settings["invert_colors"], flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
-
- gridSizer.AddGrowableCol(1)
- styleBoxSizer.Add(item = gridSizer, flag = wx.EXPAND)
-Index: gui/wxpython/Makefile
-===================================================================
---- gui/wxpython/Makefile (revision 57747)
-+++ gui/wxpython/Makefile (working copy)
-@@ -13,7 +13,7 @@
- $(wildcard animation/* core/*.py dbmgr/* gcp/*.py gmodeler/* \
- gui_core/*.py iclass/* lmgr/*.py location_wizard/*.py mapwin/*.py mapdisp/*.py \
- mapswipe/* modules/*.py nviz/*.py psmap/* rlisetup/* timeline/* vdigit/* \
-- vnet/*.py web_services/*.py wxplot/*.py) \
-+ vnet/*.py web_services/*.py wxplot/*.py scatt_plot/*.py) \
- gis_set.py gis_set_error.py wxgui.py README
-
- DSTFILES := $(patsubst %,$(ETCDIR)/%,$(SRCFILES)) \
-@@ -21,8 +21,9 @@
-
- PYDSTDIRS := $(patsubst %,$(ETCDIR)/%,animation core dbmgr gcp gmodeler \
- gui_core iclass lmgr location_wizard mapwin mapdisp modules nviz psmap \
-- mapswipe vdigit wxplot web_services rlisetup vnet timeline)
-+ mapswipe vdigit wxplot web_services rlisetup vnet timeline scatt_plot)
-
-+
- DSTDIRS := $(patsubst %,$(ETCDIR)/%,icons scripts xml)
-
- default: $(DSTFILES)
-Index: gui/wxpython/mapdisp/frame.py
-===================================================================
---- gui/wxpython/mapdisp/frame.py (revision 57747)
-+++ gui/wxpython/mapdisp/frame.py (working copy)
-@@ -231,6 +231,7 @@
- #
- self.dialogs = {}
- self.dialogs['attributes'] = None
-+ self.dialogs['scatt_plot'] = None
- self.dialogs['category'] = None
- self.dialogs['vnet'] = None
- self.dialogs['query'] = None
-@@ -1199,6 +1200,19 @@
- """!Returns toolbar with zooming tools"""
- return self.toolbars['map']
-
-+ def OnIScatt(self, event):
-+ """!Init interactive scatterplot tools
-+ """
-+ if self.dialogs['scatt_plot']:
-+ self.dialogs['scatt_plot'].Raise()
-+ return
-+
-+ from scatt_plot.frame import IScattDialog
-+ self.dialogs['scatt_plot'] = IScattDialog(parent=self, giface=self._giface)
-+
-+ self.dialogs['scatt_plot'].CenterOnScreen()
-+ self.dialogs['scatt_plot'].Show()
-+
- def OnVNet(self, event):
- """!Dialog for v.net* modules
- """
-Index: gui/wxpython/mapdisp/toolbars.py
-===================================================================
---- gui/wxpython/mapdisp/toolbars.py (revision 57747)
-+++ gui/wxpython/mapdisp/toolbars.py (working copy)
-@@ -49,6 +49,8 @@
- label = _('Create histogram of raster map')),
- 'vnet' : MetaIcon(img = 'vector-tools',
- label = _('Vector network analysis tool')),
-+ 'interact_scatter' : MetaIcon(img = 'layer-raster-profile',
-+ label = _("Interactive scatter plot tool")),
- }
-
- NvizIcons = {
-@@ -239,7 +241,9 @@
- (MapIcons["scatter"], self.parent.OnScatterplot),
- (MapIcons["histogram"], self.parent.OnHistogramPyPlot),
- (BaseIcons["histogramD"], self.parent.OnHistogram),
-- (MapIcons["vnet"], self.parent.OnVNet)))
-+ (MapIcons["vnet"], self.parent.OnVNet),
-+ (MapIcons["interact_scatter"],
-+ self.parent.OnIScatt)))
-
- def OnDecoration(self, event):
- """!Decorations overlay menu
-Index: gui/wxpython/iclass/dialogs.py
-===================================================================
---- gui/wxpython/iclass/dialogs.py (revision 57747)
-+++ gui/wxpython/iclass/dialogs.py (working copy)
-@@ -337,7 +337,6 @@
- def OnClose(self, event):
- self.catList.DeselectAll()
-
-- self.catList.UpdateChoice()
- self.Hide()
- #if not isinstance(event, wx.CloseEvent):
- #self.Destroy()
-@@ -403,12 +402,26 @@
- except UnicodeEncodeError:
- GMessage(parent = self, message = _("Please use only ASCII characters."))
- return
-+ if attr == 'color':
-+ try:
-+ colors = map(int, text.split(":"))
-+ except:
-+ return
-
-+ if len(colors) != 3:
-+ return
-
-+ for i, c in enumerate(colors):
-+ if c < 0:
-+ colors[i] = 0
-+ elif c > 255:
-+ colors[i] = 255
-+
-+ text = ":".join(map(str, colors))
-+
- cat = self.stats_data.GetCategories()[row]
- self.stats_data.GetStatistics(cat).SetStatistics(stats = {attr : text})
-
-- self.UpdateChoice()
- toolbar = self.mapWindow.toolbars['iClass']
- toolbar.choice.SetSelection(row)
- self.Select(row)
-@@ -431,7 +444,6 @@
- self.stats_data.AddStatistics(cat, name, color)
- self.SetItemCount(len(self.stats_data.GetCategories()))
-
-- self.UpdateChoice()
- self.mapWindow.UpdateChangeState(changes = True)
-
- def DeleteCategory(self):
-@@ -452,32 +464,10 @@
-
- self.SetItemCount(len(self.stats_data.GetCategories()))
-
-- self.UpdateChoice()
- self.mapWindow.UpdateChangeState(changes = True)
-
- self.mapWindow.DeleteAreas(cats = del_cats)
--
-- def UpdateChoice(self):
-- toolbar = self.mapWindow.toolbars['iClass']
-- name = toolbar.GetSelectedCategoryName()
-- catNames = []
--
-- cats = self.stats_data.GetCategories()
-- for cat in cats:
-- stat = self.stats_data.GetStatistics(cat)
-- catNames.append(stat.name)
-- toolbar.SetCategories(catNames = catNames, catIdx = cats)
-- if name in catNames:
-- toolbar.choice.SetStringSelection(name)
-- elif catNames:
-- toolbar.choice.SetSelection(0)
-
-- if toolbar.choice.IsEmpty():
-- toolbar.EnableControls(False)
-- else:
-- toolbar.EnableControls(True)
-- # don't forget to update maps, histo, ...
--
- def GetSelectedIndices(self, state = wx.LIST_STATE_SELECTED):
- indices = []
- lastFound = -1
-@@ -560,6 +550,29 @@
- def OnGetItemAttr(self, item):
- return None
-
-+ def OnGetItemAttr(self, item):
-+ back_c = wx.Colour(*map(int, self.OnGetItemText(item, 1).split(':')))
-+ text_c = wx.Colour(*ContrastColor(back_c))
-+
-+ # if it is in scope of the method, gui falls, using self solved it
-+ self.l = wx.ListItemAttr(colText = text_c, colBack = back_c)
-+ return self.l
-+
-+def ContrastColor(color):
-+ """!Decides which value shoud have text to be contrast with backgroud color (bright bg -> black, dark bg -> white)
-+
-+ @todo could be useful by other apps, consider to move it to gui_core
-+ """
-+ #gacek, http://stackoverflow.com/questions/1855884/determine-font-color-based-on-background-color
-+ a = 1 - ( 0.299 * color[0] + 0.587 * color[1] + 0.114 * color[2])/255;
-+
-+ if a < 0.5:
-+ d = 0
-+ else:
-+ d = 255
-+
-+ return (d, d, d)
-+
- class IClassSignatureFileDialog(wx.Dialog):
- def __init__(self, parent, group, subgroup,
- file = None, title = _("Save signature file"), id = wx.ID_ANY,
-Index: gui/wxpython/iclass/toolbars.py
-===================================================================
---- gui/wxpython/iclass/toolbars.py (revision 57747)
-+++ gui/wxpython/iclass/toolbars.py (working copy)
-@@ -23,7 +23,7 @@
- from core.utils import _
- from gui_core.toolbars import BaseToolbar, BaseIcons
- from icons.icon import MetaIcon
--from iclass.dialogs import IClassMapDialog
-+from iclass.dialogs import IClassMapDialog, ContrastColor
- from gui_core.forms import GUI
-
- import grass.script as grass
-@@ -46,9 +46,7 @@
- 'importAreas' : MetaIcon(img = 'layer-import',
- label = _('Import training areas from vector map')),
- 'addRgb' : MetaIcon(img = 'layer-rgb-add',
-- label = _('Add RGB map layer')),
-- 'scatt_plot' : MetaIcon(img = 'layer-raster-analyze',
-- label = _('Open Scatter Plot Tool (EXPERIMENTAL GSoC 2013)')),
-+ label = _('Add RGB map layer'))
- }
-
- class IClassMapToolbar(BaseToolbar):
-@@ -117,17 +115,16 @@
- ("zoomBack", icons["zoomBack"],
- self.parent.OnZoomBack),
- ("zoomToMap", icons["zoomExtent"],
-- self.parent.OnZoomToMap),
-- (None, ),
-- ("scatt_plot", iClassIcons["scatt_plot"],
-- self.parent.OnScatterplot)
-+ self.parent.OnZoomToMap)
- ))
- class IClassToolbar(BaseToolbar):
- """!IClass toolbar
- """
-- def __init__(self, parent):
-+ def __init__(self, parent, stats_data):
- """!IClass toolbar constructor
- """
-+ self.stats_data = stats_data
-+
- BaseToolbar.__init__(self, parent)
- self.InitToolbar(self._toolbarData())
-
-@@ -148,7 +145,12 @@
-
- self.combo.Bind(wx.EVT_COMBOBOX, self.OnStdChangeSelection)
- self.combo.Bind(wx.EVT_TEXT_ENTER, self.OnStdChangeText)
--
-+
-+ self.stats_data.statisticsAdded.connect(self.Update)
-+ self.stats_data.statisticsDeleted.connect(self.Update)
-+ self.stats_data.allStatisticsDeleted.connect(self.Update)
-+ self.stats_data.statisticsSet.connect(self.Update)
-+
- # realize the toolbar
- self.Realize()
-
-@@ -171,13 +173,30 @@
- ("sigFile", icons['sigFile'],
- self.parent.OnSaveSigFile),
- ))
--
-+
-+ def OnMotion(self, event):
-+ print self.choice.GetStringSelection()
-+
- def OnSelectCategory(self, event):
- idx = self.choice.GetSelection()
- cat = self.choice.GetClientData(idx)
--
-+
-+ self._updateColor(cat)
- self.parent.CategoryChanged(currentCat = cat)
-
-+ def _updateColor(self, cat):
-+
-+ if cat:
-+ stat = self.stats_data.GetStatistics(cat)
-+ back_c = wx.Colour(*map(int, stat.color.split(':')))
-+ text_c = wx.Colour(*ContrastColor(back_c))
-+ else:
-+ back_c = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BACKGROUND)
-+ text_c = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNTEXT)
-+
-+ self.choice.SetForegroundColour(text_c)
-+ self.choice.SetBackgroundColour(back_c)
-+
- def SetCategories(self, catNames, catIdx):
- self.choice.Clear()
- for name, idx in zip(catNames, catIdx):
-@@ -231,6 +250,33 @@
- def EnableControls(self, enable = True):
- self.combo.Enable(enable)
- self.choice.Enable(enable)
-+
-+ def Update(self, *args, **kwargs):
-+ name = self.GetSelectedCategoryName()
-+ catNames = []
-+
-+ cats = self.stats_data.GetCategories()
-+ for cat in cats:
-+ stat = self.stats_data.GetStatistics(cat)
-+ catNames.append(stat.name)
-+ self.SetCategories(catNames = catNames, catIdx = cats)
-+ if name in catNames:
-+ self.choice.SetStringSelection(name)
-+ cat = self.GetSelectedCategoryIdx()
-+ elif catNames:
-+ self.choice.SetSelection(0)
-+ cat = self.GetSelectedCategoryIdx()
-+ else:
-+ cat = None
-+
-+ if self.choice.IsEmpty():
-+ self.EnableControls(False)
-+ else:
-+ self.EnableControls(True)
-+
-+ self._updateColor(cat)
-+ self.parent.CategoryChanged(cat)
-+ # don't forget to update maps, histo, ...
-
- class IClassMapManagerToolbar(BaseToolbar):
- """!IClass toolbar
-Index: gui/wxpython/iclass/frame.py
-===================================================================
---- gui/wxpython/iclass/frame.py (revision 57747)
-+++ gui/wxpython/iclass/frame.py (working copy)
-@@ -64,6 +64,8 @@
- IClassExportAreasDialog, IClassMapDialog
- from iclass.plots import PlotPanel
-
-+from grass.pydispatch.signal import Signal
-+
- class IClassMapFrame(DoubleMapFrame):
- """! wxIClass main frame
-
-@@ -114,6 +116,12 @@
- lambda:
- self.statusbarManager.statusbarItems['coordinates'].SetAdditionalInfo(None))
- self.SetSize(size)
-+
-+ self.groupSet = Signal("IClassMapFrame.groupSet")
-+ self.categoryChanged = Signal('IClassMapFrame.categoryChanged')
-+
-+ self.InitStatistics()
-+
- #
- # Add toolbars
- #
-@@ -162,9 +170,7 @@
- Map = self.GetFirstMap())
- self.previewMapManager = MapManager(self, mapWindow = self.GetSecondWindow(),
- Map = self.GetSecondMap())
--
-- self.InitStatistics()
--
-+
- self.changes = False
- self.exportVector = None
-
-@@ -177,7 +183,7 @@
- self.dialogs['category'] = None
-
- # PyPlot init
-- self.plotPanel = PlotPanel(self, stats_data = self.stats_data)
-+ self.plotPanel = PlotPanel(self, giface = self._giface, stats_data = self.stats_data)
-
- self._addPanes()
- self._mgr.Update()
-@@ -237,7 +243,7 @@
- return False
-
- return vectorName
--
-+
- def RemoveTempVector(self):
- """!Removes temporary vector map with training areas"""
- ret = RunCommand(prog = 'g.remove',
-@@ -282,7 +288,7 @@
- BestSize((self.toolbars[name].GetBestSize())))
-
- if name == "iClass":
-- self.toolbars[name] = IClassToolbar(self)
-+ self.toolbars[name] = IClassToolbar(self, stats_data=self.stats_data)
-
- self._mgr.AddPane(self.toolbars[name],
- wx.aui.AuiPaneInfo().
-@@ -334,11 +340,12 @@
- self._addPaneMapWindow(name = 'preview')
- self._addPaneToolbar(name = 'iClassTrainingMapManager')
- self._addPaneMapWindow(name = 'training')
--
-+
-+ self._mgr.SetDockSizeConstraint(0.5, 0.5)
- self._mgr.AddPane(self.plotPanel, wx.aui.AuiPaneInfo().
- Name("plots").Caption(_("Plots")).
- Dockable(False).Floatable(False).CloseButton(False).
-- Left().Layer(1).BestSize((400, -1)))
-+ Left().Layer(1).BestSize((300, -1)))
-
- def _addPaneToolbar(self, name):
- if name == 'iClassPreviewMapManager':
-@@ -489,12 +496,14 @@
- group = grass.find_file(name=g, element='group')
- self.g['group'] = group['name']
- self.g['subgroup'] = s
-+ self.groupSet.emit(group=self.g['group'],
-+ subgroup=self.g['subgroup'])
- break
- else:
- break
-
- dlg.Destroy()
--
-+
- def OnImportAreas(self, event):
- """!Import training areas"""
- # check if we have any changes
-@@ -771,17 +780,20 @@
-
- Updates number of stddev, histograms, layer in preview display.
- """
-- stat = self.stats_data.GetStatistics(currentCat)
-- nstd = stat.nstd
-- self.toolbars['iClass'].UpdateStddev(nstd)
--
-- self.plotPanel.UpdateCategory(currentCat)
-- self.plotPanel.OnPlotTypeSelected(None)
-+ if currentCat:
-+ stat = self.stats_data.GetStatistics(currentCat)
-+ nstd = stat.nstd
-+ self.toolbars['iClass'].UpdateStddev(nstd)
-+
-+ self.plotPanel.UpdateCategory(currentCat)
-+ self.plotPanel.OnPlotTypeSelected(None)
-
-- name = stat.rasterName
-- name = self.previewMapManager.GetAlias(name)
-- if name:
-- self.previewMapManager.SelectLayer(name)
-+ name = stat.rasterName
-+ name = self.previewMapManager.GetAlias(name)
-+ if name:
-+ self.previewMapManager.SelectLayer(name)
-+
-+ self.categoryChanged.emit(cat = currentCat)
-
- def DeleteAreas(self, cats):
- """!Removes all training areas of given categories
-@@ -808,12 +820,12 @@
- def UpdateRasterName(self, newName, cat):
- """!Update alias of raster map when category name is changed"""
- origName = self.stats_data.GetStatistics(cat).rasterName
-- self.previewMapManager.SetAlias(origName, newName)
-+ self.previewMapManager.SetAlias(origName, self._addSuffix(newName))
-
- def StddevChanged(self, cat, nstd):
- """!Standard deviation multiplier changed, rerender map, histograms"""
- stat = self.stats_data.GetStatistics(cat)
-- stat.nstd = nstd
-+ stat.SetStatistics({"nstd" : nstd})
-
- if not stat.IsReady():
- return
-@@ -925,7 +937,7 @@
-
- self.ConvertToNull(name = stats.rasterName)
- self.previewMapManager.AddLayer(name = stats.rasterName,
-- alias = stats.name, resultsLayer = True)
-+ alias = self._addSuffix(stats.name), resultsLayer = True)
- # write statistics
- I_iclass_add_signature(self.signatures, statistics)
-
-@@ -938,7 +950,11 @@
-
- self.UpdateChangeState(changes = False)
- return True
--
-+
-+ def _addSuffix(self, name):
-+ suffix = _('results')
-+ return '_'.join((name, suffix))
-+
- def OnSaveSigFile(self, event):
- """!Asks for signature file name and saves it."""
- if not self.g['group']:
-@@ -1115,27 +1131,13 @@
- self.GetFirstWindow().SetModePointer()
- self.GetSecondWindow().SetModePointer()
-
-- def OnScatterplot(self, event):
-- """!Init interactive scatterplot tools
-- """
-- if self.dialogs['scatt_plot']:
-- self.dialogs['scatt_plot'].Raise()
-- return
-+ def GetMapManagers(self):
-+ """!Get map managers of wxIClass
-
-- try:
-- from scatt_plot.dialogs import ScattPlotMainDialog
-- except:
-- GError(parent = self, message = _("The Scatter Plot Tool is not installed."))
-- return
-+ @return trainingMapManager, previewMapManager
-+ """
-+ return self.trainingMapManager, self.previewMapManager
-
-- self.dialogs['scatt_plot'] = ScattPlotMainDialog(parent=self, giface=self._giface, iclass_mapwin = self.GetFirstWindow())
--
-- scatt_mgr = self.dialogs['scatt_plot'].GetScattMgr()
-- scatt_mgr.DigitDataChanged(self.toolbars['vdigit'].mapLayer.GetName(), self.GetFirstWindow().GetDigit())
--
-- self.dialogs['scatt_plot'].CenterOnScreen()
-- self.dialogs['scatt_plot'].Show()
--
- class MapManager:
- """! Class for managing map renderer.
-
-@@ -1178,7 +1180,6 @@
- self.frame.Render(self.mapWindow)
-
- if alias is not None:
-- alias = self._addSuffix(alias)
- self.layerName[alias] = name
- name = alias
- else:
-@@ -1235,7 +1236,11 @@
- self.toolbar.choice.SetSelection(0)
-
- self.frame.Render(self.mapWindow)
--
-+
-+ def Render(self):
-+ """@todo giface shoud be used instead of this method"""
-+ self.frame.Render(self.mapWindow)
-+
- def RemoveLayer(self, name, idx):
- """!Removes layer from Map and update toolbar"""
- name = self.layerName[name]
-@@ -1291,11 +1296,7 @@
- def _changeOpacity(self, layer, opacity):
- self.map.ChangeOpacity(layer=layer, opacity=opacity)
- self.frame.Render(self.mapWindow)
--
-- def _addSuffix(self, name):
-- suffix = _('results')
-- return '_'.join((name, suffix))
--
-+
- def GetAlias(self, name):
- """!Returns alias for layer"""
- name = [k for k, v in self.layerName.iteritems() if v == name]
-@@ -1306,11 +1307,11 @@
- def SetAlias(self, original, alias):
- name = self.GetAlias(original)
- if name:
-- self.layerName[self._addSuffix(alias)] = original
-+ self.layerName[alias] = original
- del self.layerName[name]
- idx = self.toolbar.choice.FindString(name)
- if idx != wx.NOT_FOUND:
-- self.toolbar.choice.SetString(idx, self._addSuffix(alias))
-+ self.toolbar.choice.SetString(idx, alias)
-
- def test():
- import core.render as render
Index: gui/wxpython/iclass/plots.py
===================================================================
---- gui/wxpython/iclass/plots.py (revision 57747)
+--- gui/wxpython/iclass/plots.py (revision 57760)
+++ gui/wxpython/iclass/plots.py (working copy)
@@ -19,6 +19,7 @@
import wx.lib.plot as plot
@@ -2558,21 +1954,9 @@
class PlotPanel(scrolled.ScrolledPanel):
"""!Panel for drawing multiple plots.
-@@ -28,7 +29,7 @@
- for each band and for one category. Coincidence plots show min max range
- of classes for each band.
- """
-- def __init__(self, parent, stats_data):
-+ def __init__(self, parent, giface, stats_data):
- scrolled.ScrolledPanel.__init__(self, parent)
-
- self.SetupScrolling(scroll_x = False, scroll_y = True)
-@@ -38,26 +39,71 @@
- self.stats_data = stats_data
+@@ -40,25 +41,68 @@
self.currentCat = None
-+ self._giface = giface
-+
self.mainSizer = wx.BoxSizer(wx.VERTICAL)
-
+
@@ -2645,7 +2029,7 @@
if self.plotSwitch.GetSelection() == 0:
stat = self.stats_data.GetStatistics(self.currentCat)
if not stat.IsReady():
-@@ -66,7 +112,10 @@
+@@ -67,7 +111,10 @@
self.DrawHistograms(stat)
else:
self.DrawCoincidencePlots()
@@ -2657,7 +2041,7 @@
def StddevChanged(self):
"""!Standard deviation multiplier changed, redraw histograms"""
if self.plotSwitch.GetSelection() == 0:
-@@ -89,7 +138,7 @@
+@@ -90,7 +137,7 @@
panel.Destroy()
self.canvasList = []
@@ -2666,7 +2050,7 @@
def ClearPlots(self):
"""!Clears plot canvases"""
for bandIdx in range(len(self.bandList)):
-@@ -104,15 +153,15 @@
+@@ -105,15 +152,15 @@
def CreatePlotCanvases(self):
"""!Create plot canvases according to the number of bands"""
for band in self.bandList:
@@ -2686,7 +2070,7 @@
self.Layout()
def UpdatePlots(self, group, subgroup, currentCat, stats_data):
-@@ -139,7 +188,7 @@
+@@ -140,7 +187,7 @@
def UpdateCategory(self, cat):
self.currentCat = cat
@@ -2695,6 +2079,62 @@
def DrawCoincidencePlots(self):
"""!Draw coincidence plots"""
for bandIdx in range(len(self.bandList)):
+Index: gui/wxpython/mapdisp/toolbars.py
+===================================================================
+--- gui/wxpython/mapdisp/toolbars.py (revision 57760)
++++ gui/wxpython/mapdisp/toolbars.py (working copy)
+@@ -49,6 +49,8 @@
+ label = _('Create histogram of raster map')),
+ 'vnet' : MetaIcon(img = 'vector-tools',
+ label = _('Vector network analysis tool')),
++ 'interact_scatter' : MetaIcon(img = 'layer-raster-profile',
++ label = _("Interactive scatter plot tool")),
+ }
+
+ NvizIcons = {
+@@ -239,7 +241,9 @@
+ (MapIcons["scatter"], self.parent.OnScatterplot),
+ (MapIcons["histogram"], self.parent.OnHistogramPyPlot),
+ (BaseIcons["histogramD"], self.parent.OnHistogram),
+- (MapIcons["vnet"], self.parent.OnVNet)))
++ (MapIcons["vnet"], self.parent.OnVNet),
++ (MapIcons["interact_scatter"],
++ self.parent.OnIScatt)))
+
+ def OnDecoration(self, event):
+ """!Decorations overlay menu
+Index: gui/wxpython/mapdisp/frame.py
+===================================================================
+--- gui/wxpython/mapdisp/frame.py (revision 57760)
++++ gui/wxpython/mapdisp/frame.py (working copy)
+@@ -231,6 +231,7 @@
+ #
+ self.dialogs = {}
+ self.dialogs['attributes'] = None
++ self.dialogs['scatt_plot'] = None
+ self.dialogs['category'] = None
+ self.dialogs['vnet'] = None
+ self.dialogs['query'] = None
+@@ -1199,6 +1200,19 @@
+ """!Returns toolbar with zooming tools"""
+ return self.toolbars['map']
+
++ def OnIScatt(self, event):
++ """!Init interactive scatterplot tools
++ """
++ if self.dialogs['scatt_plot']:
++ self.dialogs['scatt_plot'].Raise()
++ return
++
++ from scatt_plot.frame import IScattDialog
++ self.dialogs['scatt_plot'] = IScattDialog(parent=self, giface=self._giface)
++
++ self.dialogs['scatt_plot'].CenterOnScreen()
++ self.dialogs['scatt_plot'].Show()
++
+ def OnVNet(self, event):
+ """!Dialog for v.net* modules
+ """
Index: gui/wxpython/scatt_plot/__init__.py
===================================================================
--- gui/wxpython/scatt_plot/__init__.py (revision 0)
@@ -2715,7 +2155,7 @@
===================================================================
--- gui/wxpython/scatt_plot/plots.py (revision 0)
+++ gui/wxpython/scatt_plot/plots.py (working copy)
-@@ -0,0 +1,943 @@
+@@ -0,0 +1,950 @@
+"""!
+ at package scatt_plot.dialogs
+
@@ -2739,6 +2179,7 @@
+
+from copy import deepcopy
+from scatt_plot.core_c import MergeArrays, ApplyColormap
++from scatt_plot.dialogs import ManageBusyCursorMixin
+from core.settings import UserSettings
+
+try:
@@ -2760,11 +2201,13 @@
+import grass.script as grass
+from grass.pydispatch.signal import Signal
+
-+class ScatterPlotWidget(wx.Panel):
++class ScatterPlotWidget(wx.Panel, ManageBusyCursorMixin):
+ def __init__(self, parent, scatt_id, scatt_mgr, transpose,
+ id = wx.ID_ANY):
-+
++ #TODO should not be transpose and scatt_id but x, y
+ wx.Panel.__init__(self, parent, id)
++ # bacause of aui (if floatable it can not take cursor from parent)
++ ManageBusyCursorMixin.__init__(self, window=self)
+
+ self.parent = parent
+ self.full_extend = None
@@ -2799,6 +2242,7 @@
+ self.canvas.mpl_connect('button_press_event', self.OnPress)
+ self.canvas.mpl_connect('button_release_event', self.OnRelease)
+ self.canvas.mpl_connect('draw_event', self.draw_callback)
++ self.canvas.mpl_connect('figure_leave_event', self.OnLeave)
+
+ def draw_callback(self, event):
+ self.polygon_drawer.draw_callback(event)
@@ -3066,8 +2510,11 @@
+ if event.inaxes is None:
+ return
+
-+ self.cursorMove.emit(x=event.xdata, y=event.ydata)
++ self.cursorMove.emit(x=event.xdata, y=event.ydata, scatt_id=self.scatt_id)
+
++ def OnLeave(self, event):
++ self.cursorMove.emit(x=None, y=None, scatt_id=self.scatt_id)
++
+ def PanMotion(self, event):
+ 'on mouse movement'
+ if not self.mode == "pan":
@@ -3664,7 +3111,7 @@
===================================================================
--- gui/wxpython/scatt_plot/controllers.py (revision 0)
+++ gui/wxpython/scatt_plot/controllers.py (working copy)
-@@ -0,0 +1,888 @@
+@@ -0,0 +1,890 @@
+"""!
+ at package scatt_plot.controllers
+
@@ -3866,12 +3313,14 @@
+ scatt_ids = event.kwds['scatt_ids']
+ for s_id in scatt_ids:
+ trans = self.plots[s_id]['transpose']
++
+ self.plots[s_id]['scatt'] = self.guiparent.NewScatterPlot(scatt_id=s_id,
+ transpose=trans)
+
+ self.plots[s_id]['scatt'].plotClosed.connect(self.PlotClosed)
-+ self.plots[s_id]['scatt'].cursorMove.connect(lambda x, y:
-+ self.cursorPlotMove.emit(x=x, y=y))
++ self.plots[s_id]['scatt'].cursorMove.connect(lambda x, y, scatt_id:
++ self.cursorPlotMove.emit(x=x, y=y,
++ scatt_id=scatt_id))
+
+ if self.plot_mode:
+ self.plots[s_id]['scatt'].SetMode(self.plot_mode)
@@ -4689,7 +4138,7 @@
===================================================================
--- gui/wxpython/scatt_plot/dialogs.py (revision 0)
+++ gui/wxpython/scatt_plot/dialogs.py (working copy)
-@@ -0,0 +1,468 @@
+@@ -0,0 +1,494 @@
+"""!
+ at package scatt_plot.dialogs
+
@@ -4721,7 +4170,6 @@
+class AddScattPlotDialog(wx.Dialog):
+
+ def __init__(self, parent, bands, added_scatts_ids, id = wx.ID_ANY):
-+
+ wx.Dialog.__init__(self, parent, title = ("Add scatter plots"), id = id)
+
+ self.added_scatts_ids = added_scatts_ids
@@ -5158,6 +4606,33 @@
+ def OnClose(self, event):
+ """!Button 'Cancel' pressed"""
+ self.Close()
++
++class ManageBusyCursorMixin:
++ def __init__(self, window):
++ self.win = window
++
++ self.is_busy = False
++ self.cur_inside = False
++
++ self.win.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter)
++ self.win.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
++
++ def OnLeave(self, event):
++ self.cur_inside = False
++ self.busy_cur = None
++
++ def OnEnter(self, event):
++ self.cur_inside = True
++ if self.is_busy:
++ self.busy_cur = wx.BusyCursor()
++
++ def UpdateCur(self, busy):
++ self.is_busy = busy
++ if self.cur_inside and self.is_busy:
++ self.busy_cur = wx.BusyCursor()
++ return
++
++ self.busy_cur = None
\ No newline at end of file
Index: gui/wxpython/scatt_plot/toolbars.py
===================================================================
@@ -6487,7 +5962,7 @@
===================================================================
--- gui/wxpython/scatt_plot/frame.py (revision 0)
+++ gui/wxpython/scatt_plot/frame.py (working copy)
-@@ -0,0 +1,811 @@
+@@ -0,0 +1,826 @@
+"""!
+ at package scatt_plot.dialogs
+
@@ -6518,8 +5993,8 @@
+from scatt_plot.controllers import ScattsManager
+from scatt_plot.toolbars import MainToolbar, EditingToolbar, CategoryToolbar
+from scatt_plot.scatt_core import idScattToidBands
++from scatt_plot.dialogs import ManageBusyCursorMixin
+from scatt_plot.plots import ScatterPlotWidget
-+from vnet.dialogs import VnetStatusbar
+from iclass.dialogs import ContrastColor
+
+try:
@@ -6528,13 +6003,14 @@
+ import wx.lib.agw.aui as aui
+
+
-+class IClassIScattPanel(wx.Panel):
++class IClassIScattPanel(wx.Panel, ManageBusyCursorMixin):
+ def __init__(self, parent, giface, iclass_mapwin = None,
-+ id = wx.ID_ANY, style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
++ id = wx.ID_ANY):
+
+ #wx.SplitterWindow.__init__(self, parent = parent, id = id,
+ # style = wx.SP_LIVE_UPDATE)
-+ wx.Panel.__init__(self, parent = parent, id = wx.ID_ANY, **kwargs)
++ wx.Panel.__init__(self, parent = parent, id = wx.ID_ANY)
++ ManageBusyCursorMixin.__init__(self, window=self)
+
+ self.scatt_mgr = self._createScattMgr(guiparent=parent, giface=giface,
+ iclass_mapwin=iclass_mapwin)
@@ -6548,38 +6024,29 @@
+
+ self.plot_panel = ScatterPlotsPanel(self, self.scatt_mgr)
+
-+ # statusbar
-+ self.stPriors = {'high' : 5, 'info' : 1}
-+ self.stBar = VnetStatusbar(parent = self, style = 0)
-+ self.stBar.SetFieldsCount(number = 1)
-+
+ self.mainsizer = wx.BoxSizer(wx.VERTICAL)
+ self.mainsizer.Add(item = self.toolbars['mainToolbar'], proportion = 0, flag = wx.EXPAND)
+ self.mainsizer.Add(item = self.toolbars['editingToolbar'], proportion = 0, flag = wx.EXPAND)
+ self.mainsizer.Add(item = self.catsPanel, proportion = 0, flag = wx.EXPAND | wx.LEFT | wx.RIGHT , border = 5)
+ self.mainsizer.Add(item = self.plot_panel, proportion = 1, flag = wx.EXPAND)
+
-+ self.mainsizer.Add(item = self.stBar, proportion = 0)
-+
+ self.catsPanel.Hide()
+ self.toolbars['editingToolbar'].Hide()
+
+ self.SetSizer(self.mainsizer)
+
-+ self.scatt_mgr.cursorPlotMove.connect(self.CursorPlotMove)
-+ self.scatt_mgr.renderingStarted.connect(lambda : self.stBar.AddStatusItem(text=_("Rendering..."),
-+ key='comp',
-+ priority=self.stPriors['high']))
-+ self.scatt_mgr.renderingFinished.connect(lambda : self.stBar.RemoveStatusItem(key='comp'))
++ self.scatt_mgr.computingStarted.connect(lambda : self.UpdateCur(busy=True))
++ self.scatt_mgr.renderingStarted.connect(lambda : self.UpdateCur(busy=True))
++ self.scatt_mgr.renderingFinished.connect(lambda : self.UpdateCur(busy=False))
+
-+ self.scatt_mgr.computingStarted.connect(lambda : self.stBar.AddStatusItem(text=_("Computing data..."),
-+ key='comp',
-+ priority=self.stPriors['high']))
-+
+ #self.SetSashGravity(0.5)
+ #self.SplitHorizontally(self.head_panel, self.plot_panel, -50)
+ self.Layout()
+
++ def UpdateCur(self, busy):
++ self.plot_panel.SetBusy(busy)
++ ManageBusyCursorMixin.UpdateCur(self, busy)
++
+ def _selCatInIScatt(self):
+ return False
+
@@ -6589,12 +6056,6 @@
+ def _createScattMgr(self, guiparent, giface, iclass_mapwin):
+ return ScattsManager(guiparent=self, giface=giface, iclass_mapwin=iclass_mapwin)
+
-+ def CursorPlotMove(self, x, y):
-+ x = int(round(x))
-+ y = int(round(y))
-+ self.stBar.AddStatusItem(text="%d; %d" % (x, y),
-+ key='coords',
-+ priority=self.stPriors['info'])
+
+ def NewScatterPlot(self, scatt_id, transpose):
+ return self.plot_panel.NewScatterPlot(scatt_id, transpose)
@@ -6679,14 +6140,14 @@
+ return True
+
+class ScatterPlotsPanel(scrolled.ScrolledPanel):
-+ def __init__(self, parent, scatt_mgr, id = wx.ID_ANY):
++ def __init__(self, parent, scatt_mgr, id=wx.ID_ANY):
+
+ scrolled.ScrolledPanel.__init__(self, parent)
-+ self.SetupScrolling(scroll_x = False, scroll_y = True, scrollToTop = False)
++ self.SetupScrolling(scroll_x=False, scroll_y=True, scrollToTop=False)
+
+ self.scatt_mgr = scatt_mgr
+
-+ self.mainPanel = wx.Panel(parent = self, id = wx.ID_ANY)
++ self.mainPanel = wx.Panel(parent=self, id=wx.ID_ANY)
+
+ #self._createCategoryPanel()
+ # Fancy gui
@@ -6713,9 +6174,39 @@
+
+ self.scatt_i = 1
+ self.scatt_id_scatt_i = {}
++ self.transpose = {}
++ self.scatts = {}
+
+ self.Bind(wx.EVT_CLOSE, self.OnClose)
++
++ self.scatt_mgr.cursorPlotMove.connect(self.CursorPlotMove)
+
++ def SetBusy(self, busy):
++ for scatt in self.scatts.itervalues():
++ scatt.UpdateCur(busy)
++
++ def CursorPlotMove(self, x, y, scatt_id):
++
++ try:
++ x = int(round(x))
++ y = int(round(y))
++ coords = True
++ except:
++ coords = False
++
++ pane = self._getPane(scatt_id)
++ caption = self._creteCaption(scatt_id)
++ if coords:
++ caption += " %d, %d" % (x, y)
++
++ pane.Caption(caption)
++ self._mgr.RefreshCaptions()
++
++ def _getPane(self, scatt_id):
++ scatt_i = self.scatt_id_scatt_i[scatt_id]
++ name = self._getScatterPlotName(scatt_i)
++ return self._mgr.GetPane(name)
++
+ def ScatterPlotClosed(self, scatt_id):
+
+ scatt_i = self.scatt_id_scatt_i[scatt_id]
@@ -6723,6 +6214,9 @@
+ name = self._getScatterPlotName(scatt_i)
+ pane = self._mgr.GetPane(name)
+
++ del self.scatt_id_scatt_i[scatt_id]
++ del self.scatts[scatt_id]
++
+ if pane.IsOk():
+ self._mgr.ClosePane(pane)
+ self._mgr.Update()
@@ -6789,22 +6283,9 @@
+ scatt_id = scatt_id,
+ transpose = transpose)
+ scatt.plotClosed.connect(self.ScatterPlotClosed)
-+
-+ bands = self.scatt_mgr.GetBands()
-+
-+ #TODO too low level
-+ b1_id, b2_id = idScattToidBands(scatt_id, len(bands))
-+
-+ x_b = bands[b1_id].split('@')[0]
-+ y_b = bands[b2_id].split('@')[0]
-+
-+ if transpose:
-+ tmp = x_b
-+ x_b = y_b
-+ y_b = tmp
-+
-+ caption = "%s x: %s y: %s" % (_("scatter plot"), x_b, y_b)
-+
++ self.transpose[scatt_id] = transpose
++
++ caption = self._creteCaption(scatt_id)
+ self._mgr.AddPane(scatt,
+ aui.AuiPaneInfo().Dockable(True).Floatable(True).
+ Name(self._newScatterPlotName(scatt_id)).MinSize((-1, 300)).
@@ -6818,8 +6299,28 @@
+ self.SetVirtualSize(self.GetBestVirtualSize())
+ self.Layout()
+
++ self.scatts[scatt_id] = scatt
++
+ return scatt
+
++ def _creteCaption(self, scatt_id):
++
++ transpose = self.transpose[scatt_id]
++ bands = self.scatt_mgr.GetBands()
++
++ #TODO too low level
++ b1_id, b2_id = idScattToidBands(scatt_id, len(bands))
++
++ x_b = bands[b1_id].split('@')[0]
++ y_b = bands[b2_id].split('@')[0]
++
++ if transpose:
++ tmp = x_b
++ x_b = y_b
++ y_b = tmp
++
++ return "%s x: %s y: %s" % (_("scatter plot"), x_b, y_b)
++
+ def GetScattMgr(self):
+ return self.scatt_mgr
+
@@ -6939,25 +6440,7 @@
+ lastFound = index
+ indices.append(index)
+ return indices
-+ """
-+ def OnEdit(self, event):
-+ currentItem = event.m_itemIndex
-+ currentCol = event.m_col
+
-+ if currentCol == 1:
-+ dlg = wx.ColourDialog(self)
-+ dlg.GetColourData().SetChooseFull(True)
-+
-+ if dlg.ShowModal() == wx.ID_OK:
-+ color = dlg.GetColourData().GetColour().Get()
-+ color = ':'.join(map(str, color))
-+ self.SetVirtualData(currentItem, currentCol, color)
-+ dlg.Destroy()
-+ wx.CallAfter(self.SetFocus)
-+
-+ event.Skip()
-+ """
-+
+ def DeselectAll(self):
+ """!Deselect all items"""
+ indexList = self.GetSelectedIndices()
@@ -7106,9 +6589,15 @@
+ cat_idx = self.rightClickedItemIdx
+ cat_id = self.cats_mgr.GetCategories()[cat_idx]
+
-+ dlg = wx.ColourDialog(self)
++ col = self.cats_mgr.GetCategoryAttrs(cat_id)['color']
++ col = map(int, col.split(':'))
++
++ col_data = wx.ColourData()
++ col_data.SetColour(wx.Colour(*col))
++
++ dlg = wx.ColourDialog(self, col_data)
+ dlg.GetColourData().SetChooseFull(True)
-+
++
+ if dlg.ShowModal() == wx.ID_OK:
+ color = dlg.GetColourData().GetColour().Get()
+ color = ':'.join(map(str, color))
@@ -7299,3 +6788,93 @@
+
+ def GetScattId(self):
+ return self.scatt_id
++
+Index: gui/wxpython/vnet/dialogs.py
+===================================================================
+--- gui/wxpython/vnet/dialogs.py (revision 57760)
++++ gui/wxpython/vnet/dialogs.py (working copy)
+@@ -109,7 +109,7 @@
+
+ # statusbar
+ self.stPriorities = {'important' : 5, 'iformation' : 1}
+- self.stBar = VnetStatusbar(parent = self.mainPanel, style = 0)
++ self.stBar = VnetStatusbar(parent = self.mainPanel)
+ self.stBar.SetFieldsCount(number = 1)
+
+ self.def_isec_turns = None
+@@ -1218,7 +1218,7 @@
+ pos = (row, 1))
+
+ row += 1
+- gridSizer.Add(item = self.settings["invert_colors"], flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
++ gridSizer.Add(item=self.settings["invert_colors"], flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
+
+ gridSizer.AddGrowableCol(1)
+ styleBoxSizer.Add(item = gridSizer, flag = wx.EXPAND)
+@@ -1513,9 +1513,9 @@
+
+ class VnetStatusbar(wx.StatusBar):
+ """!Extends wx.StatusBar class with functionality to show multiple messages with the highest priority"""
+- def __init__(self, parent, style, id = wx.ID_ANY, **kwargs):
++ def __init__(self, parent, id = wx.ID_ANY, **kwargs):
+
+- wx.StatusBar.__init__(self, parent, id, style, **kwargs)
++ wx.StatusBar.__init__(self, parent, id, **kwargs)
+
+ self.maxPriority = 0
+ self.statusItems = []
+Index: gui/wxpython/vnet/toolbars.py
+===================================================================
+--- gui/wxpython/vnet/toolbars.py (revision 57760)
++++ gui/wxpython/vnet/toolbars.py (working copy)
+@@ -19,9 +19,9 @@
+
+ import wx
+
+-from icon import MetaIcon
++from icons.icon import MetaIcon
+ from gui_core.toolbars import BaseToolbar, BaseIcons
+-from core.gcmd import RunCommand
++from core.gcmd import RunCommand
+ from core.utils import _
+
+ class PointListToolbar(BaseToolbar):
+Index: gui/wxpython/Makefile
+===================================================================
+--- gui/wxpython/Makefile (revision 57760)
++++ gui/wxpython/Makefile (working copy)
+@@ -13,7 +13,7 @@
+ $(wildcard animation/* core/*.py dbmgr/* gcp/*.py gmodeler/* \
+ gui_core/*.py iclass/* lmgr/*.py location_wizard/*.py mapwin/*.py mapdisp/*.py \
+ mapswipe/* modules/*.py nviz/*.py psmap/* rlisetup/* timeline/* vdigit/* \
+- vnet/*.py web_services/*.py wxplot/*.py) \
++ vnet/*.py web_services/*.py wxplot/*.py scatt_plot/*.py) \
+ gis_set.py gis_set_error.py wxgui.py README
+
+ DSTFILES := $(patsubst %,$(ETCDIR)/%,$(SRCFILES)) \
+@@ -21,8 +21,9 @@
+
+ PYDSTDIRS := $(patsubst %,$(ETCDIR)/%,animation core dbmgr gcp gmodeler \
+ gui_core iclass lmgr location_wizard mapwin mapdisp modules nviz psmap \
+- mapswipe vdigit wxplot web_services rlisetup vnet timeline)
++ mapswipe vdigit wxplot web_services rlisetup vnet timeline scatt_plot)
+
++
+ DSTDIRS := $(patsubst %,$(ETCDIR)/%,icons scripts xml)
+
+ default: $(DSTFILES)
+Index: gui/icons/grass/polygon.png
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: gui/icons/grass/polygon.png
+===================================================================
+--- gui/icons/grass/polygon.png (revision 57760)
++++ gui/icons/grass/polygon.png (working copy)
+
+Property changes on: gui/icons/grass/polygon.png
+___________________________________________________________________
+Added: svn:mime-type
+## -0,0 +1 ##
++application/octet-stream
+\ No newline at end of property
More information about the grass-commit
mailing list