[GRASS-SVN] r57337 - in sandbox/turek/scatter_plot: . gui/wxpython/scatt_plot include include/defs lib/imagery
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Aug 1 03:37:21 PDT 2013
Author: turek
Date: 2013-08-01 03:37:20 -0700 (Thu, 01 Aug 2013)
New Revision: 57337
Modified:
sandbox/turek/scatter_plot/gui/wxpython/scatt_plot/controllers.py
sandbox/turek/scatter_plot/gui/wxpython/scatt_plot/core_c.py
sandbox/turek/scatter_plot/gui/wxpython/scatt_plot/dialogs.py
sandbox/turek/scatter_plot/gui/wxpython/scatt_plot/plots.py
sandbox/turek/scatter_plot/gui/wxpython/scatt_plot/sc_pl_core.py
sandbox/turek/scatter_plot/include/defs/imagery.h
sandbox/turek/scatter_plot/include/imagery.h
sandbox/turek/scatter_plot/lib/imagery/scatt.c
sandbox/turek/scatter_plot/lib/imagery/scatt_sccats.c
sandbox/turek/scatter_plot/testing_patch.diff
Log:
scatter plot: new version optimization
Modified: sandbox/turek/scatter_plot/gui/wxpython/scatt_plot/controllers.py
===================================================================
--- sandbox/turek/scatter_plot/gui/wxpython/scatt_plot/controllers.py 2013-08-01 08:33:31 UTC (rev 57336)
+++ sandbox/turek/scatter_plot/gui/wxpython/scatt_plot/controllers.py 2013-08-01 10:37:20 UTC (rev 57337)
@@ -20,7 +20,7 @@
from core.gcmd import GException, GError, RunCommand
-from scatt_plot.sc_pl_core import Core, BandsToidScatt
+from scatt_plot.sc_pl_core import Core, idBandsToidScatt
from scatt_plot.gthreading import gThread
from core.gconsole import EVT_CMD_DONE
@@ -65,7 +65,7 @@
self.iclass_conn = None
self.tasks_pids = {
- 'add_scatt' : -1,
+ 'add_scatt' : [],
'set_data' : -1,
'set_edit_cat_data' : -1,
'mapwin_conn' : [],
@@ -79,6 +79,9 @@
self.tasks_pids['set_data'] = self.thread.GetId()
self.thread.Run(callable = self.core.SetData, bands = bands)
+ #for i in range(1):
+ # self.AddScattPlot(i)
+
def SetDataDone(self, event):
self.data_set = True
self.cats_mgr.InitCoreCats()
@@ -93,7 +96,7 @@
def AddScattPlot(self, scatt_id):
- self.tasks_pids['add_scatt'] = self.thread.GetId()
+ self.tasks_pids['add_scatt'].append(self.thread.GetId())
self.thread.Run(callable = self.core.AddScattPlot, scatt_id = scatt_id)
def RenderScattPlts(self):
@@ -117,11 +120,13 @@
scatt_dt = self.scatts_dt.GetScatt(scatt_id)
cats_attrs = self.cats_mgr.GetCategoriesAttrs()
+
self.scatt_plts[scatt_id].Plot(scatt_dt, cats_attrs)
-
+ #for scatt in scatt_dt.itervalues():
+ # del scatt
self.scatt_plts[scatt_id].GetParent().Show()
+ print "ok %d" % scatt_id
-
def CleanUp(self):
self.core.CleanUp()
@@ -156,7 +161,7 @@
self.RenderScattPlts()
return
- if self.tasks_pids['add_scatt'] == event.pid:
+ if event.pid in self.tasks_pids['add_scatt']:
self.AddScattPlotDone(event)
return
Modified: sandbox/turek/scatter_plot/gui/wxpython/scatt_plot/core_c.py
===================================================================
--- sandbox/turek/scatter_plot/gui/wxpython/scatt_plot/core_c.py 2013-08-01 08:33:31 UTC (rev 57336)
+++ sandbox/turek/scatter_plot/gui/wxpython/scatt_plot/core_c.py 2013-08-01 10:37:20 UTC (rev 57337)
@@ -19,13 +19,15 @@
try:
from grass.lib.imagery import *
from grass.lib.gis import Cell_head, G_get_window
+ #from grass.lib.raster import struct_Range
+
except ImportError, e:
sys.stderr.write(_("Loading imagery lib failed"))
def ComputeScatts(region, scatt_conds, bands, n_bands, scatts, cats_rasts_in, cats_rasts_out):
- #return _computeScattsProcess(region, scatt_conds, bands, n_bands, scatts, cats_rasts_in, cats_rasts_out)
+ return _computeScattsProcess(region, scatt_conds, bands, n_bands, scatts, cats_rasts_in, cats_rasts_out, None)
# Queue object for interprocess communication
q = Queue()
@@ -41,7 +43,7 @@
def UpdateCatRast(patch_rast, region, cat_rast):
- #return ComputeScattsProcess(region, scatt_conds, bands, n_bands, scatts, cats_rasts)
+ #return _computeScattsProcess(region, scatt_conds, bands, n_bands, scatts, cats_rasts, None)
# Queue object for interprocess communication
#_updateCatRastProcess(patch_rast, region, cat_rast, None)
@@ -73,19 +75,28 @@
cell_head = _regionToCellHead(region)
ret = I_compute_scatts(pointer(cell_head),
- pointer(scatt_conds_c),
- pointer(char_bands),
- n_bands,
- pointer(sccats_c),
- pointer(char_cats_rasts_in),
- pointer(char_cats_rasts_out))
+ pointer(scatt_conds_c),
+ pointer(char_bands),
+ n_bands,
+ pointer(sccats_c),
+ pointer(char_cats_rasts_in),
+ pointer(char_cats_rasts_out))
I_sc_free_cats(pointer(sccats_c))
I_sc_free_cats(pointer(scatt_conds_c))
- output_queue.put((ret, scatts))
- #return (ret, scatts)
+ #output_queue.put((ret, scatts))
+ return (ret, scatts)
+def _getBandcRange( band_info):
+ band_c_range = struct_Range()
+
+ band_c_range.max = band_info['max']
+ band_c_range.min = band_info['min']
+
+ return band_c_range
+
+
def _regionToCellHead(region):
cell_head = struct_Cell_head()
G_get_window(pointer(cell_head))
@@ -138,24 +149,29 @@
# if key is missing condition is always True (full scatter plor is computed)
if cats[cat_id].has_key(scatt_id):
- vals = dt["np_vals"]
- #TODO hack
- vals.shape = (256 * 256)
+ vals = dt['np_vals']
+ b1_info = dt['bands_info']['b1']
+ b2_info = dt['bands_info']['b2']
- c_uint_p = ctypes.POINTER(ctypes.c_uint)
scatt_vals = scdScattData()
- if cats_type == 0:
+
+ c_void_p = ctypes.POINTER(ctypes.c_void_p)
+
+ if cats_type == SC_SCATT_DATA:
vals[:] = 0
- scatt_vals.scatt_vals_arr = vals.ctypes.data_as(c_uint_p)
-
+ elif cats_type == SC_SCATT_CONDITIONS:
+ pass
else:
- #TODO solve proble with short integer
- scatt_vals.b_conds_arr = vals.ctypes.data_as(c_uint_p)
+ return None
+ b1_c_info = _getBandcRange(b1_info)
+ b2_c_info =_getBandcRange(b2_info)
+ data_p = vals.ctypes.data_as(c_void_p)
+ I_scd_init_scatt_data(pointer(scatt_vals), cats_type, len(vals), data_p,
+ b1_c_info, b2_c_info)
+
vals_dt.append(scatt_vals)
- #vals_dt.append(data_p)
- vals.shape = (256, 256)
I_sc_insert_scatt_data(pointer(sccats),
pointer(scatt_vals),
cat_id, scatt_id)
Modified: sandbox/turek/scatter_plot/gui/wxpython/scatt_plot/dialogs.py
===================================================================
--- sandbox/turek/scatter_plot/gui/wxpython/scatt_plot/dialogs.py 2013-08-01 08:33:31 UTC (rev 57336)
+++ sandbox/turek/scatter_plot/gui/wxpython/scatt_plot/dialogs.py 2013-08-01 10:37:20 UTC (rev 57337)
@@ -28,7 +28,7 @@
from scatt_plot.controllers import ScattsManager
from scatt_plot.toolbars import MainToolbar, CategoriesToolbar
-from scatt_plot.sc_pl_core import Core, BandsToidScatt
+from scatt_plot.sc_pl_core import Core, idBandsToidScatt
from scatt_plot.plots import ScatterPlotWidget
@@ -213,7 +213,7 @@
self._createWidgets()
- self.group.SetValue("testovaci_1")
+ self.group.SetValue("B_sk")
def _createWidgets(self):
@@ -439,7 +439,7 @@
band_2 = band_1
band_1 = band_2
- self.scatt_id = BandsToidScatt(band_1, band_2, len(self.bands))
+ self.scatt_id = idBandsToidScatt(band_1, band_2, len(self.bands))
event.Skip()
Modified: sandbox/turek/scatter_plot/gui/wxpython/scatt_plot/plots.py
===================================================================
--- sandbox/turek/scatter_plot/gui/wxpython/scatt_plot/plots.py 2013-08-01 08:33:31 UTC (rev 57336)
+++ sandbox/turek/scatter_plot/gui/wxpython/scatt_plot/plots.py 2013-08-01 10:37:20 UTC (rev 57337)
@@ -131,7 +131,7 @@
"""
self.axes.clear()
- for cat_id, cat in scatts.iteritems():
+ for cat_id, scatt in scatts.iteritems():
if cat_id == 0:
cmap = matplotlib.cm.jet
cmap.set_bad('w',1.)
@@ -148,11 +148,25 @@
cmap._lut[:, 1] = int(colors[1])/255.0
cmap._lut[:, 2] = int(colors[2])/255.0
- masked_cat = np.ma.masked_less_equal(cat, 0)
+ masked_cat = np.ma.masked_less_equal(scatt['np_vals'], 0)
- self.axes.imshow(masked_cat, cmap = cmap, interpolation='nearest')
+ b1_i = scatt['bands_info']['b1']
+ b2_i = scatt['bands_info']['b2']
+
+ #self.axes.set_xlim((0, 270))
+ #self.axes.set_ylim((0, 270))
+ np.savetxt("/home/ostepok/Desktop/data.txt", scatt['np_vals'], fmt = '%d')
+
+
+ #TODO needs optimization
+ img = self.axes.imshow(masked_cat, cmap = cmap,
+ origin = 'lower',
+ extent = (b1_i['min'] - 0.5, b1_i['max'] + 0.5, b2_i['min'] - 0.5, b2_i['max'] + 0.5),
+ interpolation='nearest')
+
self.canvas.draw()
+
def on_pick(self, event):
pass
Modified: sandbox/turek/scatter_plot/gui/wxpython/scatt_plot/sc_pl_core.py
===================================================================
--- sandbox/turek/scatter_plot/gui/wxpython/scatt_plot/sc_pl_core.py 2013-08-01 08:33:31 UTC (rev 57336)
+++ sandbox/turek/scatter_plot/gui/wxpython/scatt_plot/sc_pl_core.py 2013-08-01 10:37:20 UTC (rev 57337)
@@ -15,6 +15,9 @@
import os
import sys
+#TODO
+import time
+
import numpy as np
from math import sqrt, ceil, floor
@@ -25,7 +28,8 @@
import grass.script as grass
-from core_c import CreateCatRast, ComputeScatts, UpdateCatRast
+from core_c import CreateCatRast, ComputeScatts, UpdateCatRast, \
+ SC_SCATT_DATA, SC_SCATT_CONDITIONS
class Core:
def __init__(self):
@@ -43,7 +47,7 @@
n_bands = len(self.GetBands())
self.scatts_dt.Create(n_bands)
- self.scatt_conds_dt.Create(n_bands)
+ self.scatt_conds_dt.Create(n_bands)
def AddCategory(self, cat_id):
self.scatts_dt.AddCategory(cat_id)
@@ -80,9 +84,16 @@
cats_rasts_out = self.scatts_dt.GetCatsRastsOut()
cats_rasts_in = self.scatts_dt.GetCatsRastsIn()
+
+ #for cat in scatts.itervalues():
+ # for scatt_id in cat.itervalues():
+ # print cat
+ # scatt_id.values()[0].flush()
+ # del scatt_id
+
returncode, scatts = ComputeScatts(self.an_data.GetRegion(), scatt_conds, bands,
len(self.GetBands()), scatts, cats_rasts_in, cats_rasts_out)
- self.scatts_dt.SetData(scatts)
+ #self.scatts_dt.SetData(scatts)
def SetEditCatData(self, cat_id, scatt_id, bbox, value):
@@ -95,9 +106,13 @@
bbox[k] = self._validExtend(v)
arr[bbox['btm_y'] : bbox['up_y'], bbox['btm_x'] : bbox['up_x']] = value
+ arr.flush()
+ #del arr
+ start_time = time.clock()
self.ComputeCatScatts([cat_id])
-
+ print "time"
+ print time.clock() - start_time
return True
def ComputeCatScatts(self, cats_ids):
@@ -120,7 +135,7 @@
returncode, scatts = ComputeScatts(self.an_data.GetRegion(), scatt_conds, bands,
len(self.GetBands()), scatts, cats_rasts_in, cats_rasts_out)
- self.scatts_dt.SetData(scatts)
+ #self.scatts_dt.SetData(scatts)
def CatRastUpdater(self):
return self.cat_rast_updater
@@ -193,8 +208,8 @@
def DeletedAreas(self, old_geoms, old_areas_cats):
updated_cats = []
- for i in range(len(old_geoms)):
- self._updateCatRast(old_geoms[i], old_areas_cats[i], updated_cats)
+ #for i in range(len(old_geoms)):
+ # self._updateCatRast(old_geoms[i], old_areas_cats[i], updated_cats)
return updated_cats
@@ -323,17 +338,16 @@
def __init__(self):
- self.bands = None
- self.bin_bands_f = []
+ self.bands = []
+ self.bands_info = {}
- self.region = {}
+ self.region = None
def GetRegion(self):
return self.region
def Create(self, bands):
- self.bands = None
self.bands = bands
self.region = None
@@ -345,11 +359,53 @@
if ret != 0:
raise GException("g.region failed:\n%s" % msg)
+
+ self.bands_info = {}
+ for b in bands:
+ self.bands_info[b] = self._getRasterInfo(b)
+ if self.bands_info[b]["datatype"] != "CELL":
+ raise GException(_("Raster <%s> is not <CELL> type.") % (b))
+ #TODO size of raster check
+
self.region = self._parseRegion(region)
+ def _getRasterInfo(self, rast):
+ """
+ """
+ ret, out, msg = RunCommand("r.info",
+ map = rast,
+ flags = "rg",
+ getErrorMsg = True,
+ read = True)
+
+ if ret != 0:
+ raise GException("r.info failed:\n%s" % msg)
+
+ out = out.split("\n")
+ raster_info = {}
+
+ for b in out:
+ if not b.strip():
+ continue
+ k, v = b.split("=")
+ if k == "datatype":
+ pass
+ elif k in ['rows', 'cols', 'cells', 'min', 'max']:
+ v = int(v)
+ else:
+ v = float(v)
+
+ raster_info[k] = v
+
+ return raster_info
+
def GetBands(self):
return self.bands
+ def GetBandInfo(self, band_id):
+ band = self.bands[band_id]
+ return self.bands_info[band]
+
def _parseRegion(self, region_str):
region = {}
@@ -371,10 +427,10 @@
self.an_data = an_data
+ #TODO
self.max_n_cats = 10
- self.vals = 256 * 256
-
+ self.dtype = 'uint8'
self.type = 1;
self.CleanUp()
@@ -432,22 +488,30 @@
if self.cats[cat_id].has_key(scatt_id):
return 0
- if self.type == 0:
- np_vals = np.zeros(self.vals, dtype = 'uint32')
- elif self.type == 1:
- #TODO solve proble with short
- np_vals = np.zeros(self.vals, dtype = 'uint32')
- else:
- return -1
+ b_i = self.GetBandsInfo(scatt_id)
- np_vals.shape = (256, 256)#TODO hack do it general
+ shape = (b_i['b2']['max'] - b_i['b2']['min'] + 1, b_i['b1']['max'] - b_i['b1']['min'] + 1)
+ np_vals = np.memmap(grass.tempfile(), dtype=self.dtype, mode='w+', shape = shape)
+ np_vals.flush()
+
self.cats[cat_id][scatt_id] = {
'np_vals' : np_vals
}
return 1
+ def GetBandsInfo(self, scatt_id):
+ b1, b2 = idScattToidBands(scatt_id, len(self.an_data.GetBands()))
+
+ b1_info = self.an_data.GetBandInfo(b1)
+ b2_info = self.an_data.GetBandInfo(b2)
+
+ bands_info = {'b1' : b1_info,
+ 'b2' : b2_info}
+
+ return bands_info
+
def DeleScattPlot(self, cat_id, scatt_id):
if not self.cats.has_key(cat_id):
@@ -478,7 +542,8 @@
for scatt_id in scatt_ids:
# if key is missing condition is always True (full scatter plor is computed)
if self.cats[cat_id].has_key(scatt_id):
- cats[cat_id][scatt_id] = {'np_vals' : self.cats[cat_id][scatt_id]['np_vals']}
+ cats[cat_id][scatt_id] = {'np_vals' : self.cats[cat_id][scatt_id]['np_vals'],
+ 'bands_info' : self.GetBandsInfo(scatt_id)}
return cats
@@ -500,6 +565,8 @@
ScattPlotsCondsData.__init__(self, an_data)
+ self.dtype = 'uint32'
+
#TODO
self.type = 0
@@ -564,8 +631,8 @@
scatts = {}
for cat_id in self.cats.iterkeys():
- scatts[cat_id] = self.cats[cat_id][scatt_id]['np_vals']
-
+ scatts[cat_id] = {'np_vals' : self.cats[cat_id][scatt_id]['np_vals'],
+ 'bands_info' : self.GetBandsInfo(scatt_id)}
return scatts
def CleanUp(self):
@@ -604,7 +671,7 @@
return cats_rasts_out
#TODO move to utils?
-def idScattToBands(scatt_id, n_bands):
+def idScattToidBands(scatt_id, n_bands):
n_b1 = n_bands - 1
@@ -615,17 +682,16 @@
return band_1, band_2
-def BandsToidScatt(band_1, band_2, n_bands):
+def idBandsToidScatt(band_1_id, band_2_id, n_bands):
- if band_2 < band_1:
+ if band_2_id < band_1_id:
tmp = band_1
- band_1 = band_2
- band_2 = tmp
+ band_1_id = band_2_id
+ band_2_id = tmp
-
n_b1 = n_bands - 1
- scatt_id = (band_1 * (2 * n_b1 + 1) - band_1 * band_1) / 2 + band_2 - band_1 - 1
+ scatt_id = (band_1_id * (2 * n_b1 + 1) - band_1_id * band_1_id) / 2 + band_2_id - band_1_id - 1
return scatt_id
Modified: sandbox/turek/scatter_plot/include/defs/imagery.h
===================================================================
--- sandbox/turek/scatter_plot/include/defs/imagery.h 2013-08-01 08:33:31 UTC (rev 57336)
+++ sandbox/turek/scatter_plot/include/defs/imagery.h 2013-08-01 10:37:20 UTC (rev 57337)
@@ -120,9 +120,9 @@
int I_sc_remove_scatt_data(struct scCats *, struct scdScattData *, int, int);
int I_sc_set_value(struct scCats *, int, int, int, int);
-void I_scd_init_scatt_data(struct scdScattData *, int, int);
+void I_scd_init_scatt_data(struct scdScattData *, int, int, void *, struct Range, struct Range);
void I_scd_free_scatt_data(struct scdScattData *);
-int I_scd_get_data_size(struct scdScattData *);
+void I_scd_get_range_min_max(struct scdScattData *, CELL *, CELL *, CELL *, CELL *);
void * I_scd_get_data_ptr(struct scdScattData *);
int I_scd_set_value(struct scdScattData *, unsigned int, unsigned int);
Modified: sandbox/turek/scatter_plot/include/imagery.h
===================================================================
--- sandbox/turek/scatter_plot/include/imagery.h 2013-08-01 08:33:31 UTC (rev 57336)
+++ sandbox/turek/scatter_plot/include/imagery.h 2013-08-01 10:37:20 UTC (rev 57337)
@@ -155,18 +155,25 @@
struct scScatts
{
int n_a_scatts;
-
+
int * scatts_bands;
int * scatt_idxs;
struct scdScattData ** scatts_arr;
};
+#define SC_SCATT_DATA 0
+#define SC_SCATT_CONDITIONS 1
+
struct scdScattData
{
- int n_vals;
- //TODO void pointer???
- unsigned int * b_conds_arr;
+ int n_vals; //TODO delete???
+
+ struct Range band_1_range;
+ struct Range band_2_range;
+
+
+ unsigned char * b_conds_arr;
unsigned int * scatt_vals_arr;
};
Modified: sandbox/turek/scatter_plot/lib/imagery/scatt.c
===================================================================
--- sandbox/turek/scatter_plot/lib/imagery/scatt.c 2013-08-01 08:33:31 UTC (rev 57336)
+++ sandbox/turek/scatter_plot/lib/imagery/scatt.c 2013-08-01 10:37:20 UTC (rev 57337)
@@ -231,22 +231,31 @@
static inline void update_cat_scatt_plt(CELL ** chunks, char ** null_chunks, int chunk_size, unsigned short * belongs_pix, struct scScatts * scatts)
{
- int band_axis_1, band_axis_2, i_scatt, array_idx, cat_idx, i_chunks_pix;
- int r_bits = 256;
+ int band_axis_1, band_axis_2, i_scatt, array_idx, cat_idx, i_chunks_pix, max_arr_idx;
- CELL * band_1_chunks;
- CELL * band_2_chunks;
+ CELL * b_1_chunks;
+ CELL * b_2_chunks;
char * band_1_null_chunks,* band_2_null_chunks;
+ struct Range b_1_range, b_2_range;
+ int b_1_range_size;
+
int * scatts_bands = scatts->scatts_bands;
+
for(i_scatt = 0; i_scatt < scatts->n_a_scatts; i_scatt++)
{
- band_1_chunks = chunks[scatts_bands[i_scatt * 2]];
- band_2_chunks = chunks[scatts_bands[i_scatt * 2 + 1]];
+ b_1_chunks = chunks[scatts_bands[i_scatt * 2]];
+ b_2_chunks = chunks[scatts_bands[i_scatt * 2 + 1]];
band_1_null_chunks = null_chunks[scatts_bands[i_scatt * 2]];
band_2_null_chunks = null_chunks[scatts_bands[i_scatt * 2 + 1]];
+ b_1_range = scatts->scatts_arr[i_scatt]->band_1_range;
+ b_2_range = scatts->scatts_arr[i_scatt]->band_2_range;
+
+ b_1_range_size = b_1_range.max - b_1_range.min + 1;
+ max_arr_idx = (b_1_range.max - b_1_range.min + 1) * (b_2_range.max - b_2_range.min + 1);
+
for(i_chunks_pix = 0; i_chunks_pix < chunk_size; i_chunks_pix++)
{
if(!belongs_pix[i_chunks_pix] ||
@@ -254,8 +263,12 @@
band_2_null_chunks[i_chunks_pix] == 1)
continue;
- array_idx = band_1_chunks[i_chunks_pix] + band_2_chunks[i_chunks_pix] * r_bits;
+ array_idx = b_1_chunks[i_chunks_pix] - b_1_range.min + (b_2_chunks[i_chunks_pix] - b_2_range.min) * b_1_range_size;
+ if(array_idx < 0 || array_idx >= max_arr_idx) {
+ G_warning ("pixel out of range");
+ continue;
+ }
++scatts->scatts_arr[i_scatt]->scatt_vals_arr[array_idx];
}
}
@@ -267,21 +280,22 @@
{
int i_chunks_pix, i_cat, i_scatt, n_a_scatts, i_cond;
- int cat_id, scatt_plts_cat_idx, array_idx;
+ int cat_id, scatt_plts_cat_idx, array_idx, max_arr_idx;
char * band_1_null_chunks,* band_2_null_chunks;
- int r_bits = 256;
-
struct scScatts * scatts_conds;
struct scScatts * scatt_plts_scatts;
struct scdScattData * conds;
+ struct Range b_1_range, b_2_range;
+ int b_1_range_size;
+
int * scatts_bands;
struct scdScattData ** scatts_arr;
- CELL * band_1_chunks;
- CELL * band_2_chunks;
- unsigned int * i_scatt_conds;
+ CELL * b_1_chunks;
+ CELL * b_2_chunks;
+ unsigned char * i_scatt_conds;
unsigned short * belongs_pix = (unsigned short *) G_malloc(chunk_size * sizeof(unsigned short));
unsigned char * rast_pixs = (unsigned char *) G_malloc(chunk_size * sizeof(unsigned char));
@@ -330,14 +344,22 @@
// test every defined conditions in scatter plots
for(i_scatt = 0; i_scatt < scatts_conds->n_a_scatts; i_scatt++)
{
- band_1_chunks = chunks[scatts_bands[i_scatt * 2]];
- band_2_chunks = chunks[scatts_bands[i_scatt * 2 + 1]];
+ b_1_chunks = chunks[scatts_bands[i_scatt * 2]];
+ b_2_chunks = chunks[scatts_bands[i_scatt * 2 + 1]];
band_1_null_chunks = null_chunks[scatts_bands[i_scatt * 2]];
band_2_null_chunks = null_chunks[scatts_bands[i_scatt * 2 + 1]];
i_scatt_conds = scatts_conds->scatts_arr[i_scatt]->b_conds_arr;
+ b_1_range = scatts_conds->scatts_arr[i_scatt]->band_1_range;
+ b_2_range = scatts_conds->scatts_arr[i_scatt]->band_2_range;
+
+ b_1_range_size = b_1_range.max - b_1_range.min + 1;
+
+ max_arr_idx = (b_1_range.max - b_1_range.min + 1) * (b_2_range.max - b_2_range.min + 1);
+ //G_message("max_arr_idx scatt_conds: %d", max_arr_idx);
+
for(i_chunks_pix = 0; i_chunks_pix < chunk_size; i_chunks_pix++)
{
if(belongs_pix[i_chunks_pix] ||
@@ -345,7 +367,13 @@
band_2_null_chunks[i_chunks_pix] == 1)
continue;
- if(i_scatt_conds[band_1_chunks[i_chunks_pix] + band_2_chunks[i_chunks_pix] * r_bits])
+ array_idx = b_1_chunks[i_chunks_pix] - b_1_range.min + (b_2_chunks[i_chunks_pix] - b_2_range.min) * b_1_range_size;
+ /*TODO test value */
+ if(array_idx < 0 || array_idx >= max_arr_idx) {
+ G_warning ("pixel out of range");
+ continue;
+ }
+ if(i_scatt_conds[array_idx])
belongs_pix[i_chunks_pix] = 1;
}
}
Modified: sandbox/turek/scatter_plot/lib/imagery/scatt_sccats.c
===================================================================
--- sandbox/turek/scatter_plot/lib/imagery/scatt_sccats.c 2013-08-01 08:33:31 UTC (rev 57336)
+++ sandbox/turek/scatter_plot/lib/imagery/scatt_sccats.c 2013-08-01 10:37:20 UTC (rev 57337)
@@ -162,7 +162,7 @@
}
-int I_sc_insert_scatt_data(struct scCats * cats, struct scdScattData * scatt_vals, int cat_id, int scatt_id)
+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;
@@ -181,10 +181,10 @@
if(scatts->scatt_idxs[scatt_id] >= 0)
return -1;
- if(!scatt_vals->b_conds_arr && cats->type == 1)
+ if(!scatt_data->b_conds_arr && cats->type == SC_SCATT_CONDITIONS)
return -1;
- if(!scatt_vals->scatt_vals_arr && cats->type == 0)
+ if(!scatt_data->scatt_vals_arr && cats->type == SC_SCATT_DATA)
return -1;
n_a_scatts = scatts->n_a_scatts;
@@ -196,13 +196,13 @@
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_vals;
+ scatts->scatts_arr[n_a_scatts] = scatt_data;
++scatts->n_a_scatts;
return 0;
}
-int I_sc_remove_scatt_data(struct scCats * cats, struct scdScattData * scatt_vals, int cat_id, int scatt_id)
+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;
@@ -221,7 +221,7 @@
if(scatts->scatt_idxs[scatt_id] < 0)
return -1;
- scatt_vals = scatts->scatts_arr[scatt_idx];
+ scatt_data = scatts->scatts_arr[scatt_idx];
for(i_scatt = scatt_idx; i_scatt < scatts->n_a_scatts - 1; i_scatt++)
{
@@ -233,7 +233,7 @@
scatts->scatt_idxs[scatt_id] = -1;
- scatt_vals = scatts->scatts_arr[scatt_id];
+ scatt_data = scatts->scatts_arr[scatt_id];
scatts->n_a_scatts--;
return 0;
@@ -259,61 +259,82 @@
return 0;
}
-void I_scd_init_scatt_data(struct scdScattData * scatt_vals, int n_vals, int type)
+void I_scd_init_scatt_data(struct scdScattData * scatt_data, int type, int n_vals, void * data,
+ struct Range band_1_range, struct Range band_2_range)
{
- scatt_vals->n_vals = n_vals;
+ scatt_data->n_vals = n_vals;
- if(type == 0)
+ scatt_data->band_1_range.min = band_1_range.min;
+ scatt_data->band_1_range.max = band_1_range.max;
+ scatt_data->band_1_range.first_time = 0;
+
+ scatt_data->band_2_range.min = band_2_range.min;
+ scatt_data->band_2_range.max = band_2_range.max;
+ scatt_data->band_2_range.first_time = 0;
+
+ if(type == SC_SCATT_DATA)
{
- scatt_vals->scatt_vals_arr = (unsigned int *) malloc(n_vals * sizeof(unsigned int));
- memset(scatt_vals->scatt_vals_arr, 0, n_vals * sizeof(unsigned int));
- scatt_vals->b_conds_arr = NULL;
+ if(data)
+ scatt_data->scatt_vals_arr = (unsigned int *) data;
+ else {
+ scatt_data->scatt_vals_arr = (unsigned int *) 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 == 1)
- {
- scatt_vals->b_conds_arr = (unsigned short *) malloc(n_vals * sizeof(unsigned short));
- memset(scatt_vals->b_conds_arr, 0, n_vals * sizeof(unsigned short));
- scatt_vals->scatt_vals_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 *) 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;
}
-void I_scd_free_scatt_data(struct scdScattData * scatt_vals)
+void I_scd_free_scatt_data(struct scdScattData * scatt_data)
{
- free(scatt_vals->b_conds_arr);
- free(scatt_vals->scatt_vals_arr);
+ free(scatt_data->b_conds_arr);
+ free(scatt_data->scatt_vals_arr);
- scatt_vals = NULL;
+ scatt_data = NULL;
return;
}
-int I_scd_get_data_size(struct scdScattData * scatt_vals)
+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)
{
- return scatt_vals->n_vals;
+
+ 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;
}
-void * I_scd_get_data_ptr(struct scdScattData * scatt_vals)
+void * I_scd_get_data_ptr(struct scdScattData * scatt_data)
{
- if(!scatt_vals->b_conds_arr)
- return scatt_vals->b_conds_arr;
- else if(!scatt_vals->scatt_vals_arr)
- return scatt_vals->scatt_vals_arr;
+ 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_vals, unsigned int val_idx, unsigned int val)
+int I_scd_set_value(struct scdScattData * scatt_data, unsigned int val_idx, unsigned int val)
{
- if(val_idx < 0 && val_idx > scatt_vals->n_vals)
+ if(val_idx < 0 && val_idx > scatt_data->n_vals)
return -1;
- if(scatt_vals->b_conds_arr)
- scatt_vals->b_conds_arr[val_idx] = val;
- else if(scatt_vals->scatt_vals_arr)
- scatt_vals->scatt_vals_arr[val_idx] = val;
+ 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;
Modified: sandbox/turek/scatter_plot/testing_patch.diff
===================================================================
--- sandbox/turek/scatter_plot/testing_patch.diff 2013-08-01 08:33:31 UTC (rev 57336)
+++ sandbox/turek/scatter_plot/testing_patch.diff 2013-08-01 10:37:20 UTC (rev 57337)
@@ -1,6 +1,6 @@
Index: vector/v.edit/main.c
===================================================================
---- vector/v.edit/main.c (revision 57285)
+--- vector/v.edit/main.c (revision 57336)
+++ vector/v.edit/main.c (working copy)
@@ -299,7 +299,7 @@
move_z = atof(params.move->answers[2]);
@@ -32,9 +32,9 @@
case MODE_BREAK:
Index: include/imagery.h
===================================================================
---- include/imagery.h (revision 57285)
+--- include/imagery.h (revision 57336)
+++ include/imagery.h (working copy)
-@@ -135,6 +135,41 @@
+@@ -135,6 +135,48 @@
} IClass_statistics;
@@ -58,27 +58,68 @@
+struct scScatts
+{
+ int n_a_scatts;
-+
++
+ int * scatts_bands;
+ int * scatt_idxs;
+
+ struct scdScattData ** scatts_arr;
+};
+
++#define SC_SCATT_DATA 0
++#define SC_SCATT_CONDITIONS 1
++
+struct scdScattData
+{
-+ int n_vals;
-+ //TODO void pointer???
-+ unsigned int * b_conds_arr;
++ int n_vals; //TODO delete???
++
++ struct Range band_1_range;
++ struct Range band_2_range;
++
++
++ unsigned char * b_conds_arr;
+ unsigned int * scatt_vals_arr;
+};
+
#define SIGNATURE_TYPE_MIXED 1
#define GROUPFILE "CURGROUP"
+Index: include/defs/imagery.h
+===================================================================
+--- include/defs/imagery.h (revision 57336)
++++ include/defs/imagery.h (working copy)
+@@ -110,6 +110,29 @@
+ FILE *I_fopen_subgroup_ref_new(const char *, const char *);
+ FILE *I_fopen_subgroup_ref_old(const char *, const char *);
+
++/* scatt_plt.c */
++void I_sc_init_cats(struct scCats *, int, int);
++void I_sc_free_cats(struct scCats *);
++void I_sc_get_active_categories(int *, int *, struct scCats *);
++int I_sc_add_cat(struct scCats *, int);
++int I_sc_delete_cat(struct scCats *, int);
++int I_sc_insert_scatt_data(struct scCats *, struct scdScattData *, int, int);
++int I_sc_remove_scatt_data(struct scCats *, struct scdScattData *, int, int);
++int I_sc_set_value(struct scCats *, int, int, int, int);
++
++void I_scd_init_scatt_data(struct scdScattData *, int, int, void *, struct Range, struct Range);
++void I_scd_free_scatt_data(struct scdScattData *);
++void I_scd_get_range_min_max(struct scdScattData *, CELL *, CELL *, CELL *, CELL *);
++void * I_scd_get_data_ptr(struct scdScattData *);
++int I_scd_set_value(struct scdScattData *, unsigned int, unsigned int);
++
++int I_compute_scatts(struct Cell_head *, struct scCats *, const char **,
++ int, struct scCats *, const char **, const char **);
++
++int I_create_cat_rast(struct Cell_head *, const char *);
++int I_insert_patch_to_cat_rast(const char *, struct Cell_head *, const char *);
++
++
+ /* sig.c */
+ int I_init_signatures(struct Signature *, int);
+ int I_new_signature(struct Signature *);
Index: include/defs/vedit.h
===================================================================
---- include/defs/vedit.h (revision 57285)
+--- include/defs/vedit.h (revision 57336)
+++ include/defs/vedit.h (working copy)
@@ -34,7 +34,7 @@
@@ -104,45 +145,534 @@
/* zbulk.c */
int Vedit_bulk_labeling(struct Map_info *, struct ilist *,
-Index: include/defs/imagery.h
+Index: gui/wxpython/scatt_plot/controllers.py
===================================================================
---- include/defs/imagery.h (revision 57285)
-+++ include/defs/imagery.h (working copy)
-@@ -110,6 +110,29 @@
- FILE *I_fopen_subgroup_ref_new(const char *, const char *);
- FILE *I_fopen_subgroup_ref_old(const char *, const char *);
-
-+/* scatt_plt.c */
-+void I_sc_init_cats(struct scCats *, int, int);
-+void I_sc_free_cats(struct scCats *);
-+void I_sc_get_active_categories(int *, int *, struct scCats *);
-+int I_sc_add_cat(struct scCats *, int);
-+int I_sc_delete_cat(struct scCats *, int);
-+int I_sc_insert_scatt_data(struct scCats *, struct scdScattData *, int, int);
-+int I_sc_remove_scatt_data(struct scCats *, struct scdScattData *, int, int);
-+int I_sc_set_value(struct scCats *, int, int, int, int);
+--- gui/wxpython/scatt_plot/controllers.py (revision 0)
++++ gui/wxpython/scatt_plot/controllers.py (working copy)
+@@ -0,0 +1,518 @@
++"""!
++ at package scatt_plot.controllers
+
-+void I_scd_init_scatt_data(struct scdScattData *, int, int);
-+void I_scd_free_scatt_data(struct scdScattData *);
-+int I_scd_get_data_size(struct scdScattData *);
-+void * I_scd_get_data_ptr(struct scdScattData *);
-+int I_scd_set_value(struct scdScattData *, unsigned int, unsigned int);
++ at brief Controller layer for scatter plot tool.
+
-+int I_compute_scatts(struct Cell_head *, struct scCats *, const char **,
-+ int, struct scCats *, const char **, const char **);
++Classes:
+
-+int I_create_cat_rast(struct Cell_head *, const char *);
-+int I_insert_patch_to_cat_rast(const char *, struct Cell_head *, const char *);
++(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.
+
- /* sig.c */
- int I_init_signatures(struct Signature *, int);
- int I_new_signature(struct Signature *);
++ at author Stepan Turek <stepan.turek seznam.cz> (mentor: Martin Landa)
++"""
++import os
++import sys
++
++#TODO
++import wx
++
++from core.gcmd import GException, GError, RunCommand
++
++from scatt_plot.sc_pl_core import Core, idBandsToidScatt
++
++from scatt_plot.gthreading import gThread
++from core.gconsole import EVT_CMD_DONE
++
++from grass.pydispatch.signal import Signal
++
++class ScattsManager(wx.EvtHandler):
++ def __init__(self, guiparent, giface, iclass_mapwin):
++ #TODO remove iclass parameter
++
++ wx.EvtHandler.__init__(self)
++ self.giface = giface
++ self.mapDisp = giface.GetMapDisplay()
++ self.mapWin = giface.GetMapWindow()
++
++ if iclass_mapwin:
++ self.mapWin = iclass_mapwin
++
++ self.guiparent = guiparent
++
++ self.core = Core()
++ self.scatts_dt = self.core.GetScattsData()
++
++ self.cats_mgr = CategoriesManager(self, self.core)
++
++ self.thread = gThread(self);
++
++ self.scatt_plts = {}
++ self.added_cats_rasts = {}
++
++ self.cats_to_update = []
++
++ self.edit_cat_type = None
++
++ self.data_set = False
++
++ if iclass_mapwin:
++ self.mapWin_conn = MapWinConnection(self, self.mapWin, self.core.CatRastUpdater())
++ self.iclass_conn = IClassConnection(self, iclass_mapwin.parent, self.cats_mgr)
++ else:
++ self.mapWin_conn = None
++ self.iclass_conn = None
++
++ self.tasks_pids = {
++ 'add_scatt' : [],
++ 'set_data' : -1,
++ 'set_edit_cat_data' : -1,
++ 'mapwin_conn' : [],
++ 'render_plots' : -1
++ }
++
++ self.Bind(EVT_CMD_DONE, self.OnThreadDone)
++
++ def SetData(self, bands):
++ self.data_set = False
++ self.tasks_pids['set_data'] = self.thread.GetId()
++ self.thread.Run(callable = self.core.SetData, bands = bands)
++
++ #for i in range(1):
++ # self.AddScattPlot(i)
++
++ def SetDataDone(self, event):
++ self.data_set = True
++ self.cats_mgr.InitCoreCats()
++
++ def OnOutput(self, event):
++ """!Print thread output according to debug level.
++ """
++ print event.text
++
++ def GetBands(self):
++ return self.core.GetBands()
++
++ def AddScattPlot(self, scatt_id):
++
++ self.tasks_pids['add_scatt'].append(self.thread.GetId())
++ self.thread.Run(callable = self.core.AddScattPlot, scatt_id = scatt_id)
++
++ def RenderScattPlts(self):
++
++ cats_attrs = self.cats_mgr.GetCategoriesAttrs()
++ for scatt_id, scatt in self.scatt_plts.iteritems():
++ scatt_dt = self.scatts_dt.GetScatt(scatt_id)
++ scatt.Plot(scatt_dt, cats_attrs)
++
++
++ def AddScattPlotDone(self, event):
++
++ scatt_id = event.kwds['scatt_id']
++
++ #TODO guiparent - not very good
++ self.scatt_plts[scatt_id] = self.guiparent.NewScatterPlot(scatt_id = scatt_id)
++
++ if self.edit_cat_type:
++ self.scatt_plts[scatt_id].StartCategoryEdit()
++
++ scatt_dt = self.scatts_dt.GetScatt(scatt_id)
++
++ cats_attrs = self.cats_mgr.GetCategoriesAttrs()
++
++ self.scatt_plts[scatt_id].Plot(scatt_dt, cats_attrs)
++ #for scatt in scatt_dt.itervalues():
++ # del scatt
++ self.scatt_plts[scatt_id].GetParent().Show()
++ print "ok %d" % scatt_id
++
++ def CleanUp(self):
++ self.core.CleanUp()
++
++ for scatt_id, scatt in self.scatt_plts.items():
++ scatt.CleanUp()
++ del self.scatt_plts[scatt_id]
++
++ def OnThreadDone(self, event):
++
++ if event.exception:
++ GError(str(event.exception))
++ return
++
++ if event.pid in self.tasks_pids['mapwin_conn']:
++ self.tasks_pids['mapwin_conn'].remove(event.pid)
++ updated_cats = event.ret
++
++ for cat in updated_cats:
++ if cat not in self.cats_to_update:
++ self.cats_to_update.append(cat)
++
++ if not self.tasks_pids['mapwin_conn']:
++ self.tasks_pids['render_plots'] = self.thread.GetId()
++ self.thread.Run(callable = self.core.ComputeCatScatts,
++ cats_ids = self.cats_to_update[:])
++ del self.cats_to_update[:]
++
++ return
++
++ if self.tasks_pids['render_plots'] == event.pid:
++ #TODO how to put it to the thread - kils gui
++ self.RenderScattPlts()
++ return
++
++ if event.pid in self.tasks_pids['add_scatt']:
++ self.AddScattPlotDone(event)
++ return
++
++ if self.tasks_pids['set_data'] == event.pid:
++ self.SetDataDone(event)
++ return
++
++ if self.tasks_pids['set_edit_cat_data'] == event.pid:
++ self.SetEditCatDataDone(event)
++ return
++
++ def EditCat(self, edit_type):
++
++ self.edit_cat_type = edit_type
++
++ if self.edit_cat_type:
++ for scatt in self.scatt_plts.itervalues():
++ scatt.StopCategoryEdit()
++ scatt.StartCategoryEdit()
++
++ else:
++ for scatt in self.scatt_plts.itervalues():
++ scatt.StopCategoryEdit()
++
++ def SetEditCatData(self, scatt_id, bbox):
++
++ value = 1
++ if self.edit_cat_type == 'remove':
++ value = 0
++
++ self.tasks_pids['set_edit_cat_data'] = self.thread.GetId()
++
++ sel_cat_id = self.cats_mgr.GetSelectedCat()
++
++ self.thread.Run(callable = self.core.SetEditCatData,
++ scatt_id = scatt_id,
++ cat_id = sel_cat_id,
++ bbox = bbox,
++ value = value)
++
++ def SetEditCatDataDone(self, event):
++
++ self.RenderScattPlts()
++
++ cat_id = event.kwds["cat_id"]
++
++ cat_rast = self.core.GetCatRastOut(cat_id)
++
++
++ if cat_rast not in self.added_cats_rasts.values():
++
++ cats_attrs = self.cats_mgr.GetCategoryAttrs(cat_id)
++
++ #TODO use standard raster lib
++ name = "cat_%d" % cat_id
++ ret, err_msg = RunCommand('r.external',
++ output = name,
++ getErrorMsg = True,
++ input = cat_rast,
++ flags = "o",
++ overwrite = True)
++
++ if ret != 0:
++ GError(_("r.external failed\n%s" % err_msg))
++
++ region = self.core.GetRegion()
++ ret, err_msg = RunCommand('r.region',
++ map = name,
++ getErrorMsg = True,
++ n = "%f" % region['n'],
++ s = "%f" % region['s'],
++ e = "%f" % region['e'],
++ w = "%f" % region['w'],
++ )
++
++ region = self.core.GetRegion()
++ ret, err_msg = RunCommand('r.colors',
++ map = name,
++ rules = "-",
++ stdin = "1 %s" % cats_attrs["color"],
++ getErrorMsg = True)
++
++ if ret != 0:
++ GError(_("r.region failed\n%s" % err_msg))
++
++ self.mapWin.Map.AddLayer(ltype = "raster", name = "cat_%d" % cat_id, render = True,
++ command = ["d.rast", "map=%s" % name, "values=1"])
++
++ #elif self.giface.GetLayerTree():
++ # self.giface.GetLayerTree().AddLayer("raster", lname = "cat_%d" % cat_id, lchecked = True,
++ # lcmd = ["d.rast", "map=%s" % name, "values=1"])
++
++ if ret != 0:
++ GError(_("r.region failed\n%s" % err_msg))
++
++ self.added_cats_rasts[cat_id] = cat_rast
++
++ self.giface.updateMap.emit()
++
++ def DigitDataChanged(self, vectMap, digit):
++
++ if self.mapWin_conn:
++ self.mapWin_conn.DigitDataChanged(vectMap, digit)
++ return 1
++ else:
++ return 0
++
++ def GetCategoriesManager(self):
++ return self.cats_mgr
++
++class CategoriesManager:
++
++ def __init__(self, scatt_mgr, core):
++
++ self.core = core
++ self.scatt_mgr = scatt_mgr
++
++ self.cats = {}
++ self.cats_ids = []
++
++ self.sel_cat_id = -1
++
++ self.initialized = Signal('CategoriesManager.initialized')
++ self.setCategoryAttrs = Signal('CategoriesManager.setCategoryAttrs')
++ self.deletedCategory = Signal('CategoriesManager.deletedCategory')
++ self.addedCategory = Signal('CategoriesManager.addedCategory')
++
++ def Clear(self):
++
++ self.cats.clear()
++ del self.cats_ids[:]
++
++ self.sel_cat_id = -1
++
++ def InitCoreCats(self):
++ if self.scatt_mgr.data_set:
++ for cat_id in self.cats_ids:
++ self.core.AddCategory(cat_id)
++
++ def AddCategory(self, cat_id = None, name = None, color = None):
++
++ if cat_id is None:
++ if self.cats_ids:
++ cat_id = max(self.cats_ids) + 1
++ else:
++ cat_id = 1
++
++ if self.scatt_mgr.data_set:
++ ret = self.core.AddCategory(cat_id)
++ if ret < 0: #TODO
++ return -1;
++
++ self.cats[cat_id] = {
++ 'name' : _('Category %s' % cat_id ),
++ 'color' : "0:0:0"
++ }
++ self.cats_ids.append(cat_id)
++
++ if name is not None:
++ self.cats[cat_id]["name"] = name
++
++ if color is not None:
++ self.cats[cat_id]["color"] = color
++
++ self.addedCategory.emit(cat_id = cat_id,
++ name = self.cats[cat_id]["name"],
++ color = self.cats[cat_id]["color"] )
++ return cat_id
++
++ def SetCategoryAttrs(self, cat_id, attrs_dict):
++ for k, v in attrs_dict.iteritems():
++ self.cats[cat_id][k] = v
++
++ self.setCategoryAttrs.emit(cat_id = cat_id, attrs_dict = attrs_dict)
++
++ def DeleteCategory(self, cat_id):
++
++ if self.scatt_mgr.data_set:
++ self.core.DeleteCategory(cat_id)
++ del self.cats[cat_id]
++ self.cats_ids.remove(cat_id)
++
++ self.deletedCategory.emit(cat_id = cat_id)
++
++ #TODO emit event?
++ def SetSelectedCat(self, cat_id):
++ self.sel_cat_id = cat_id
++
++ def GetSelectedCat(self):
++ return self.sel_cat_id
++
++ def GetCategoryAttrs(self, cat_id):
++ #TODO is mutable
++ return self.cats[cat_id]
++
++ def GetCategoriesAttrs(self):
++ #TODO is mutable
++ return self.cats
++
++ def GetCategories(self):
++ return self.cats_ids[:]
++
++class MapWinConnection:
++ def __init__(self, scatt_mgr, mapWin, scatt_rast_updater):
++ self.mapWin = mapWin
++ self.vectMap = None
++ self.scatt_rast_updater = scatt_rast_updater
++ self.scatt_mgr = scatt_mgr
++ self.cats_mgr = scatt_mgr.cats_mgr
++
++ self.thread = self.scatt_mgr.thread
++
++ #TODO
++ self.mapWin.parent.toolbars["vdigit"].editingStarted.connect(self.DigitDataChanged)
++
++ #def ChangeMap(self, vectMap, layers_cats):
++ # self.vectMap = vectMap
++ # self.layers_cats = layers_cats
++
++ #ret, region, msg = RunCommand("v.to.rast",
++ # flags = "gp",
++ # getErrorMsg = True,
++ # read = True)
++
++ def _connectSignals(self):
++ self.digit.featureAdded.connect(self.AddFeature)
++ self.digit.areasDeleted.connect(self.DeleteAreas)
++ self.digit.featuresDeleted.connect(self.DeleteAreas)
++ self.digit.vertexMoved.connect(self.ChangeVertex)
++ self.digit.vertexRemoved.connect(self.ChangeVertex)
++ self.digit.lineEdited.connect(self.ChangeVertex)
++ self.digit.featuresMoved.connect(self.MoveFeatures)
++
++ def AddFeature(self, new_geom, cat):
++ if not self.scatt_mgr.data_set:
++ return
++
++ self.scatt_mgr.tasks_pids['mapwin_conn'].append(self.thread.GetId())
++ self.thread.Run(callable = self.scatt_rast_updater.AddedFeature,
++ new_geom = new_geom,
++ cat = cat)
++
++ def DeleteAreas(self, old_geoms, old_areas_cats):
++ if not self.scatt_mgr.data_set:
++ return
++
++ self.scatt_mgr.tasks_pids['mapwin_conn'].append(self.thread.GetId())
++ self.thread.Run(callable = self.scatt_rast_updater.DeletedAreas,
++ old_geoms = old_geoms,
++ old_areas_cats = old_areas_cats)
++
++ def ChangeVertex(self, new_geom, new_areas_cats, old_geom, old_areas_cats):
++ if not self.scatt_mgr.data_set:
++ return
++
++ self.scatt_mgr.tasks_pids['mapwin_conn'].append(self.thread.GetId())
++ self.thread.Run(callable = self.scatt_rast_updater.ChangedVertex,
++ new_geom = new_geom,
++ old_geom = old_geom,
++ old_areas_cats = old_areas_cats,
++ new_areas_cats = new_areas_cats)
++
++ def MoveFeatures(self, old_geoms, old_areas_cats, new_areas_cats, move):
++ if not self.scatt_mgr.data_set:
++ return
++
++ self.scatt_mgr.tasks_pids['mapwin_conn'].append(self.thread.GetId())
++ self.thread.Run(callable = self.scatt_rast_updater.MovedFeatures,
++ move = move,
++ old_geoms = old_geoms,
++ old_areas_cats = old_areas_cats,
++ new_areas_cats = new_areas_cats)
++
++ def DigitDataChanged(self, vectMap, digit):
++
++ self.digit = digit
++ self.vectMap = vectMap
++
++ self.scatt_rast_updater.SetVectMap(vectMap)
++
++ self._connectSignals()
++
++class IClassConnection:
++ def __init__(self, scatt_mgr, iclass_frame, cats_mgr):
++ self.iclass_frame = iclass_frame
++ self.stats_data = self.iclass_frame.stats_data
++ self.cats_mgr = cats_mgr
++ self.scatt_mgr = scatt_mgr
++
++ self.stats_data.statisticsAdded.connect(self.AddCategory)
++ self.stats_data.statisticsDeleted.connect(self.DeleteCategory)
++ self.stats_data.allStatisticsDeleted.connect(self.DeletAllCategories)
++ self.stats_data.statisticsSet.connect(self.SetCategory)
++
++ self.cats_mgr.setCategoryAttrs.connect(self.SetStatistics)
++ self.cats_mgr.deletedCategory.connect(self.DeleteStatistics)
++ self.cats_mgr.addedCategory.connect(self.AddStatistics)
++
++ self.SyncCats()
++
++ def SyncCats(self):
++ self.cats_mgr.addedCategory.disconnect(self.AddStatistics)
++ cats = self.stats_data.GetCategories()
++ for c in cats:
++ stats = self.stats_data.GetStatistics(c)
++ self.cats_mgr.AddCategory(c, stats.name, stats.color)
++ self.cats_mgr.addedCategory.connect(self.AddStatistics)
++
++ def AddCategory(self, cat, name, color):
++ self.cats_mgr.addedCategory.disconnect(self.AddStatistics)
++ self.cats_mgr.AddCategory(cat_id = cat, name = name, color = color)
++ self.cats_mgr.addedCategory.connect(self.AddStatistics)
++
++ def DeleteCategory(self, cat):
++ self.cats_mgr.deletedCategory.disconnect(self.DeleteStatistics)
++ self.cats_mgr.DeleteCategory(cat)
++ self.cats_mgr.deletedCategory.connect(self.DeleteStatistics)
++
++
++ def DeletAllCategories(self):
++
++ self.cats_mgr.deletedCategory.disconnect(self.DeleteStatistics)
++ cats = self.stats_data.GetCategories()
++ for c in cats:
++ self.cats_mgr.DeleteCategory(c)
++ self.cats_mgr.deletedCategory.connect(self.DeleteStatistics)
++
++ def SetCategory(self, cat, stats):
++
++ self.cats_mgr.setCategoryAttrs.disconnect(self.SetStatistics)
++ cats_attr = {}
++ for attr in ['name', 'color']:
++ if stats.has_key(attr):
++ cats_attr[attr] = stats[attr]
++
++ if cats_attr:
++ self.cats_mgr.SetCategoryAttrs(cat, cats_attr)
++ self.cats_mgr.setCategoryAttrs.connect(self.SetStatistics)
++
++
++ def SetStatistics(self, cat_id, attrs_dict):
++ self.stats_data.statisticsSet.disconnect(self.SetCategory)
++ self.stats_data.GetStatistics(cat_id).SetStatistics(attrs_dict)
++ self.stats_data.statisticsSet.connect(self.SetCategory)
++
++ def AddStatistics(self, cat_id, name, color):
++ self.stats_data.statisticsAdded.disconnect(self.AddCategory)
++ self.stats_data.AddStatistics(cat_id, name, color)
++ self.stats_data.statisticsAdded.connect(self.AddCategory)
++
++ def DeleteStatistics(self, cat_id):
++ self.stats_data.statisticsDeleted.disconnect(self.DeleteCategory)
++ self.stats_data.DeleteStatistics(cat_id)
++ self.stats_data.statisticsDeleted.connect(self.DeleteCategory)
Index: gui/wxpython/scatt_plot/sc_pl_core.py
===================================================================
--- gui/wxpython/scatt_plot/sc_pl_core.py (revision 0)
+++ gui/wxpython/scatt_plot/sc_pl_core.py (working copy)
-@@ -0,0 +1,631 @@
+@@ -0,0 +1,697 @@
+"""!
+ at package scatt_plot.scatt_plot
+
@@ -160,6 +690,9 @@
+import os
+import sys
+
++#TODO
++import time
++
+import numpy as np
+
+from math import sqrt, ceil, floor
@@ -170,7 +703,8 @@
+
+import grass.script as grass
+
-+from core_c import CreateCatRast, ComputeScatts, UpdateCatRast
++from core_c import CreateCatRast, ComputeScatts, UpdateCatRast, \
++ SC_SCATT_DATA, SC_SCATT_CONDITIONS
+
+class Core:
+ def __init__(self):
@@ -188,7 +722,7 @@
+ n_bands = len(self.GetBands())
+
+ self.scatts_dt.Create(n_bands)
-+ self.scatt_conds_dt.Create(n_bands)
++ self.scatt_conds_dt.Create(n_bands)
+
+ def AddCategory(self, cat_id):
+ self.scatts_dt.AddCategory(cat_id)
@@ -225,9 +759,16 @@
+ cats_rasts_out = self.scatts_dt.GetCatsRastsOut()
+ cats_rasts_in = self.scatts_dt.GetCatsRastsIn()
+
++
++ #for cat in scatts.itervalues():
++ # for scatt_id in cat.itervalues():
++ # print cat
++ # scatt_id.values()[0].flush()
++ # del scatt_id
++
+ returncode, scatts = ComputeScatts(self.an_data.GetRegion(), scatt_conds, bands,
+ len(self.GetBands()), scatts, cats_rasts_in, cats_rasts_out)
-+ self.scatts_dt.SetData(scatts)
++ #self.scatts_dt.SetData(scatts)
+
+ def SetEditCatData(self, cat_id, scatt_id, bbox, value):
+
@@ -240,9 +781,13 @@
+ bbox[k] = self._validExtend(v)
+
+ arr[bbox['btm_y'] : bbox['up_y'], bbox['btm_x'] : bbox['up_x']] = value
++ arr.flush()
++ #del arr
+
++ start_time = time.clock()
+ self.ComputeCatScatts([cat_id])
-+
++ print "time"
++ print time.clock() - start_time
+ return True
+
+ def ComputeCatScatts(self, cats_ids):
@@ -265,7 +810,7 @@
+ returncode, scatts = ComputeScatts(self.an_data.GetRegion(), scatt_conds, bands,
+ len(self.GetBands()), scatts, cats_rasts_in, cats_rasts_out)
+
-+ self.scatts_dt.SetData(scatts)
++ #self.scatts_dt.SetData(scatts)
+
+ def CatRastUpdater(self):
+ return self.cat_rast_updater
@@ -338,8 +883,8 @@
+ def DeletedAreas(self, old_geoms, old_areas_cats):
+
+ updated_cats = []
-+ for i in range(len(old_geoms)):
-+ self._updateCatRast(old_geoms[i], old_areas_cats[i], updated_cats)
++ #for i in range(len(old_geoms)):
++ # self._updateCatRast(old_geoms[i], old_areas_cats[i], updated_cats)
+
+ return updated_cats
+
@@ -468,17 +1013,16 @@
+
+ def __init__(self):
+
-+ self.bands = None
-+ self.bin_bands_f = []
++ self.bands = []
++ self.bands_info = {}
+
-+ self.region = {}
++ self.region = None
+
+ def GetRegion(self):
+ return self.region
+
+ def Create(self, bands):
+
-+ self.bands = None
+ self.bands = bands
+ self.region = None
+
@@ -490,11 +1034,53 @@
+ if ret != 0:
+ raise GException("g.region failed:\n%s" % msg)
+
++
++ self.bands_info = {}
++ for b in bands:
++ self.bands_info[b] = self._getRasterInfo(b)
++ if self.bands_info[b]["datatype"] != "CELL":
++ raise GException(_("Raster <%s> is not <CELL> type.") % (b))
++ #TODO size of raster check
++
+ self.region = self._parseRegion(region)
+
++ def _getRasterInfo(self, rast):
++ """
++ """
++ ret, out, msg = RunCommand("r.info",
++ map = rast,
++ flags = "rg",
++ getErrorMsg = True,
++ read = True)
++
++ if ret != 0:
++ raise GException("r.info failed:\n%s" % msg)
++
++ out = out.split("\n")
++ raster_info = {}
++
++ for b in out:
++ if not b.strip():
++ continue
++ k, v = b.split("=")
++ if k == "datatype":
++ pass
++ elif k in ['rows', 'cols', 'cells', 'min', 'max']:
++ v = int(v)
++ else:
++ v = float(v)
++
++ raster_info[k] = v
++
++ return raster_info
++
+ def GetBands(self):
+ return self.bands
+
++ def GetBandInfo(self, band_id):
++ band = self.bands[band_id]
++ return self.bands_info[band]
++
+ def _parseRegion(self, region_str):
+
+ region = {}
@@ -516,10 +1102,10 @@
+
+ self.an_data = an_data
+
++ #TODO
+ self.max_n_cats = 10
+
-+ self.vals = 256 * 256
-+
++ self.dtype = 'uint8'
+ self.type = 1;
+ self.CleanUp()
+
@@ -577,22 +1163,30 @@
+ if self.cats[cat_id].has_key(scatt_id):
+ return 0
+
-+ if self.type == 0:
-+ np_vals = np.zeros(self.vals, dtype = 'uint32')
-+ elif self.type == 1:
-+ #TODO solve proble with short
-+ np_vals = np.zeros(self.vals, dtype = 'uint32')
-+ else:
-+ return -1
++ b_i = self.GetBandsInfo(scatt_id)
+
-+ np_vals.shape = (256, 256)#TODO hack do it general
++ shape = (b_i['b2']['max'] - b_i['b2']['min'] + 1, b_i['b1']['max'] - b_i['b1']['min'] + 1)
+
++ np_vals = np.memmap(grass.tempfile(), dtype=self.dtype, mode='w+', shape = shape)
++ np_vals.flush()
++
+ self.cats[cat_id][scatt_id] = {
+ 'np_vals' : np_vals
+ }
+
+ return 1
+
++ def GetBandsInfo(self, scatt_id):
++ b1, b2 = idScattToidBands(scatt_id, len(self.an_data.GetBands()))
++
++ b1_info = self.an_data.GetBandInfo(b1)
++ b2_info = self.an_data.GetBandInfo(b2)
++
++ bands_info = {'b1' : b1_info,
++ 'b2' : b2_info}
++
++ return bands_info
++
+ def DeleScattPlot(self, cat_id, scatt_id):
+
+ if not self.cats.has_key(cat_id):
@@ -623,7 +1217,8 @@
+ for scatt_id in scatt_ids:
+ # if key is missing condition is always True (full scatter plor is computed)
+ if self.cats[cat_id].has_key(scatt_id):
-+ cats[cat_id][scatt_id] = {'np_vals' : self.cats[cat_id][scatt_id]['np_vals']}
++ cats[cat_id][scatt_id] = {'np_vals' : self.cats[cat_id][scatt_id]['np_vals'],
++ 'bands_info' : self.GetBandsInfo(scatt_id)}
+
+ return cats
+
@@ -645,6 +1240,8 @@
+
+ ScattPlotsCondsData.__init__(self, an_data)
+
++ self.dtype = 'uint32'
++
+ #TODO
+ self.type = 0
+
@@ -709,8 +1306,8 @@
+
+ scatts = {}
+ for cat_id in self.cats.iterkeys():
-+ scatts[cat_id] = self.cats[cat_id][scatt_id]['np_vals']
-+
++ scatts[cat_id] = {'np_vals' : self.cats[cat_id][scatt_id]['np_vals'],
++ 'bands_info' : self.GetBandsInfo(scatt_id)}
+ return scatts
+
+ def CleanUp(self):
@@ -749,7 +1346,7 @@
+ return cats_rasts_out
+
+#TODO move to utils?
-+def idScattToBands(scatt_id, n_bands):
++def idScattToidBands(scatt_id, n_bands):
+
+ n_b1 = n_bands - 1
+
@@ -760,17 +1357,16 @@
+ return band_1, band_2
+
+
-+def BandsToidScatt(band_1, band_2, n_bands):
++def idBandsToidScatt(band_1_id, band_2_id, n_bands):
+
-+ if band_2 < band_1:
++ if band_2_id < band_1_id:
+ tmp = band_1
-+ band_1 = band_2
-+ band_2 = tmp
++ band_1_id = band_2_id
++ band_2_id = tmp
+
-+
+ n_b1 = n_bands - 1
+
-+ scatt_id = (band_1 * (2 * n_b1 + 1) - band_1 * band_1) / 2 + band_2 - band_1 - 1
++ scatt_id = (band_1_id * (2 * n_b1 + 1) - band_1_id * band_1_id) / 2 + band_2_id - band_1_id - 1
+
+ return scatt_id
+
@@ -948,7 +1544,7 @@
+
+from scatt_plot.controllers import ScattsManager
+from scatt_plot.toolbars import MainToolbar, CategoriesToolbar
-+from scatt_plot.sc_pl_core import Core, BandsToidScatt
++from scatt_plot.sc_pl_core import Core, idBandsToidScatt
+from scatt_plot.plots import ScatterPlotWidget
+
+
@@ -1133,7 +1729,7 @@
+
+
+ self._createWidgets()
-+ self.group.SetValue("testovaci_1")
++ self.group.SetValue("B_sk")
+
+ def _createWidgets(self):
+
@@ -1359,7 +1955,7 @@
+ band_2 = band_1
+ band_1 = band_2
+
-+ self.scatt_id = BandsToidScatt(band_1, band_2, len(self.bands))
++ self.scatt_id = idBandsToidScatt(band_1, band_2, len(self.bands))
+
+ event.Skip()
+
@@ -1646,7 +2242,7 @@
===================================================================
--- gui/wxpython/scatt_plot/core_c.py (revision 0)
+++ gui/wxpython/scatt_plot/core_c.py (working copy)
-@@ -0,0 +1,211 @@
+@@ -0,0 +1,227 @@
+"""!
+ at package scatt_plot.scatt_plot
+
@@ -1668,13 +2264,15 @@
+try:
+ from grass.lib.imagery import *
+ from grass.lib.gis import Cell_head, G_get_window
++ #from grass.lib.raster import struct_Range
+
++
+except ImportError, e:
+ sys.stderr.write(_("Loading imagery lib failed"))
+
+def ComputeScatts(region, scatt_conds, bands, n_bands, scatts, cats_rasts_in, cats_rasts_out):
+
-+ #return _computeScattsProcess(region, scatt_conds, bands, n_bands, scatts, cats_rasts_in, cats_rasts_out)
++ return _computeScattsProcess(region, scatt_conds, bands, n_bands, scatts, cats_rasts_in, cats_rasts_out, None)
+
+ # Queue object for interprocess communication
+ q = Queue()
@@ -1690,7 +2288,7 @@
+
+def UpdateCatRast(patch_rast, region, cat_rast):
+
-+ #return ComputeScattsProcess(region, scatt_conds, bands, n_bands, scatts, cats_rasts)
++ #return _computeScattsProcess(region, scatt_conds, bands, n_bands, scatts, cats_rasts, None)
+ # Queue object for interprocess communication
+
+ #_updateCatRastProcess(patch_rast, region, cat_rast, None)
@@ -1722,19 +2320,28 @@
+ cell_head = _regionToCellHead(region)
+
+ ret = I_compute_scatts(pointer(cell_head),
-+ pointer(scatt_conds_c),
-+ pointer(char_bands),
-+ n_bands,
-+ pointer(sccats_c),
-+ pointer(char_cats_rasts_in),
-+ pointer(char_cats_rasts_out))
++ pointer(scatt_conds_c),
++ pointer(char_bands),
++ n_bands,
++ pointer(sccats_c),
++ pointer(char_cats_rasts_in),
++ pointer(char_cats_rasts_out))
+
+ I_sc_free_cats(pointer(sccats_c))
+ I_sc_free_cats(pointer(scatt_conds_c))
+
-+ output_queue.put((ret, scatts))
-+ #return (ret, scatts)
++ #output_queue.put((ret, scatts))
++ return (ret, scatts)
+
++def _getBandcRange( band_info):
++ band_c_range = struct_Range()
++
++ band_c_range.max = band_info['max']
++ band_c_range.min = band_info['min']
++
++ return band_c_range
++
++
+def _regionToCellHead(region):
+ cell_head = struct_Cell_head()
+ G_get_window(pointer(cell_head))
@@ -1787,24 +2394,29 @@
+ # if key is missing condition is always True (full scatter plor is computed)
+ if cats[cat_id].has_key(scatt_id):
+
-+ vals = dt["np_vals"]
-+ #TODO hack
-+ vals.shape = (256 * 256)
++ vals = dt['np_vals']
++ b1_info = dt['bands_info']['b1']
++ b2_info = dt['bands_info']['b2']
+
-+ c_uint_p = ctypes.POINTER(ctypes.c_uint)
+ scatt_vals = scdScattData()
-+ if cats_type == 0:
++
++ c_void_p = ctypes.POINTER(ctypes.c_void_p)
++
++ if cats_type == SC_SCATT_DATA:
+ vals[:] = 0
-+ scatt_vals.scatt_vals_arr = vals.ctypes.data_as(c_uint_p)
-+
++ elif cats_type == SC_SCATT_CONDITIONS:
++ pass
+ else:
-+ #TODO solve proble with short integer
-+ scatt_vals.b_conds_arr = vals.ctypes.data_as(c_uint_p)
++ return None
+
++ b1_c_info = _getBandcRange(b1_info)
++ b2_c_info =_getBandcRange(b2_info)
++ data_p = vals.ctypes.data_as(c_void_p)
++ I_scd_init_scatt_data(pointer(scatt_vals), cats_type, len(vals), data_p,
++ b1_c_info, b2_c_info)
++
+ vals_dt.append(scatt_vals)
+
-+ #vals_dt.append(data_p)
-+ vals.shape = (256, 256)
+ I_sc_insert_scatt_data(pointer(sccats),
+ pointer(scatt_vals),
+ cat_id, scatt_id)
@@ -1875,7 +2487,7 @@
===================================================================
--- gui/wxpython/scatt_plot/plots.py (revision 0)
+++ gui/wxpython/scatt_plot/plots.py (working copy)
-@@ -0,0 +1,185 @@
+@@ -0,0 +1,199 @@
+"""!
+ at package scatt_plot.dialogs
+
@@ -2009,7 +2621,7 @@
+ """
+
+ self.axes.clear()
-+ for cat_id, cat in scatts.iteritems():
++ for cat_id, scatt in scatts.iteritems():
+ if cat_id == 0:
+ cmap = matplotlib.cm.jet
+ cmap.set_bad('w',1.)
@@ -2026,11 +2638,25 @@
+ cmap._lut[:, 1] = int(colors[1])/255.0
+ cmap._lut[:, 2] = int(colors[2])/255.0
+
-+ masked_cat = np.ma.masked_less_equal(cat, 0)
++ masked_cat = np.ma.masked_less_equal(scatt['np_vals'], 0)
+
-+ self.axes.imshow(masked_cat, cmap = cmap, interpolation='nearest')
+
++ b1_i = scatt['bands_info']['b1']
++ b2_i = scatt['bands_info']['b2']
++
++ #self.axes.set_xlim((0, 270))
++ #self.axes.set_ylim((0, 270))
++ np.savetxt("/home/ostepok/Desktop/data.txt", scatt['np_vals'], fmt = '%d')
++
++
++ #TODO needs optimization
++ img = self.axes.imshow(masked_cat, cmap = cmap,
++ origin = 'lower',
++ extent = (b1_i['min'] - 0.5, b1_i['max'] + 0.5, b2_i['min'] - 0.5, b2_i['max'] + 0.5),
++ interpolation='nearest')
++
+ self.canvas.draw()
++
+
+ def on_pick(self, event):
+ pass
@@ -2062,527 +2688,55 @@
+ self.parent.OnPlotClosed(self.scatt_id)
+ self.Destroy()
\ No newline at end of file
-Index: gui/wxpython/scatt_plot/controllers.py
+Index: gui/wxpython/mapdisp/toolbars.py
===================================================================
---- gui/wxpython/scatt_plot/controllers.py (revision 0)
-+++ gui/wxpython/scatt_plot/controllers.py (working copy)
-@@ -0,0 +1,513 @@
-+"""!
-+ at package scatt_plot.controllers
-+
-+ at brief Controller layer for scatter plot tool.
-+
-+Classes:
-+
-+(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.
-+
-+ at author Stepan Turek <stepan.turek seznam.cz> (mentor: Martin Landa)
-+"""
-+import os
-+import sys
-+
-+#TODO
-+import wx
-+
-+from core.gcmd import GException, GError, RunCommand
-+
-+from scatt_plot.sc_pl_core import Core, BandsToidScatt
-+
-+from scatt_plot.gthreading import gThread
-+from core.gconsole import EVT_CMD_DONE
-+
-+from grass.pydispatch.signal import Signal
-+
-+class ScattsManager(wx.EvtHandler):
-+ def __init__(self, guiparent, giface, iclass_mapwin):
-+ #TODO remove iclass parameter
-+
-+ wx.EvtHandler.__init__(self)
-+ self.giface = giface
-+ self.mapDisp = giface.GetMapDisplay()
-+ self.mapWin = giface.GetMapWindow()
-+
-+ if iclass_mapwin:
-+ self.mapWin = iclass_mapwin
-+
-+ self.guiparent = guiparent
-+
-+ self.core = Core()
-+ self.scatts_dt = self.core.GetScattsData()
-+
-+ self.cats_mgr = CategoriesManager(self, self.core)
-+
-+ self.thread = gThread(self);
-+
-+ self.scatt_plts = {}
-+ self.added_cats_rasts = {}
-+
-+ self.cats_to_update = []
-+
-+ self.edit_cat_type = None
-+
-+ self.data_set = False
-+
-+ if iclass_mapwin:
-+ self.mapWin_conn = MapWinConnection(self, self.mapWin, self.core.CatRastUpdater())
-+ self.iclass_conn = IClassConnection(self, iclass_mapwin.parent, self.cats_mgr)
-+ else:
-+ self.mapWin_conn = None
-+ self.iclass_conn = None
-+
-+ self.tasks_pids = {
-+ 'add_scatt' : -1,
-+ 'set_data' : -1,
-+ 'set_edit_cat_data' : -1,
-+ 'mapwin_conn' : [],
-+ 'render_plots' : -1
-+ }
-+
-+ self.Bind(EVT_CMD_DONE, self.OnThreadDone)
-+
-+ def SetData(self, bands):
-+ self.data_set = False
-+ self.tasks_pids['set_data'] = self.thread.GetId()
-+ self.thread.Run(callable = self.core.SetData, bands = bands)
-+
-+ def SetDataDone(self, event):
-+ self.data_set = True
-+ self.cats_mgr.InitCoreCats()
-+
-+ def OnOutput(self, event):
-+ """!Print thread output according to debug level.
+--- gui/wxpython/mapdisp/toolbars.py (revision 57336)
++++ gui/wxpython/mapdisp/toolbars.py (working copy)
+@@ -243,7 +243,8 @@
+ (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["scatter"], self.parent.OnScatterplot2)))
+
+ def OnDecoration(self, event):
+ """!Decorations overlay menu
+Index: gui/wxpython/mapdisp/frame.py
+===================================================================
+--- gui/wxpython/mapdisp/frame.py (revision 57336)
++++ gui/wxpython/mapdisp/frame.py (working copy)
+@@ -207,6 +207,7 @@
+ #
+ self.dialogs = {}
+ self.dialogs['attributes'] = None
++ self.dialogs['scatt_plot'] = None
+ self.dialogs['category'] = None
+ self.dialogs['barscale'] = None
+ self.dialogs['legend'] = None
+@@ -1301,6 +1302,19 @@
+ """!Returns toolbar with zooming tools"""
+ return self.toolbars['map']
+
++ def OnScatterplot2(self, event):
++ """!Init interactive scatterplot tools
+ """
-+ print event.text
-+
-+ def GetBands(self):
-+ return self.core.GetBands()
-+
-+ def AddScattPlot(self, scatt_id):
-+
-+ self.tasks_pids['add_scatt'] = self.thread.GetId()
-+ self.thread.Run(callable = self.core.AddScattPlot, scatt_id = scatt_id)
-+
-+ def RenderScattPlts(self):
-+
-+ cats_attrs = self.cats_mgr.GetCategoriesAttrs()
-+ for scatt_id, scatt in self.scatt_plts.iteritems():
-+ scatt_dt = self.scatts_dt.GetScatt(scatt_id)
-+ scatt.Plot(scatt_dt, cats_attrs)
-+
-+
-+ def AddScattPlotDone(self, event):
-+
-+ scatt_id = event.kwds['scatt_id']
-+
-+ #TODO guiparent - not very good
-+ self.scatt_plts[scatt_id] = self.guiparent.NewScatterPlot(scatt_id = scatt_id)
-+
-+ if self.edit_cat_type:
-+ self.scatt_plts[scatt_id].StartCategoryEdit()
-+
-+ scatt_dt = self.scatts_dt.GetScatt(scatt_id)
-+
-+ cats_attrs = self.cats_mgr.GetCategoriesAttrs()
-+ self.scatt_plts[scatt_id].Plot(scatt_dt, cats_attrs)
-+
-+ self.scatt_plts[scatt_id].GetParent().Show()
-+
-+
-+ def CleanUp(self):
-+ self.core.CleanUp()
-+
-+ for scatt_id, scatt in self.scatt_plts.items():
-+ scatt.CleanUp()
-+ del self.scatt_plts[scatt_id]
-+
-+ def OnThreadDone(self, event):
-+
-+ if event.exception:
-+ GError(str(event.exception))
++ if self.dialogs['scatt_plot']:
++ self.dialogs['scatt_plot'].Raise()
+ return
+
-+ if event.pid in self.tasks_pids['mapwin_conn']:
-+ self.tasks_pids['mapwin_conn'].remove(event.pid)
-+ updated_cats = event.ret
-+
-+ for cat in updated_cats:
-+ if cat not in self.cats_to_update:
-+ self.cats_to_update.append(cat)
-+
-+ if not self.tasks_pids['mapwin_conn']:
-+ self.tasks_pids['render_plots'] = self.thread.GetId()
-+ self.thread.Run(callable = self.core.ComputeCatScatts,
-+ cats_ids = self.cats_to_update[:])
-+ del self.cats_to_update[:]
-+
-+ return
-+
-+ if self.tasks_pids['render_plots'] == event.pid:
-+ #TODO how to put it to the thread - kils gui
-+ self.RenderScattPlts()
-+ return
-+
-+ if self.tasks_pids['add_scatt'] == event.pid:
-+ self.AddScattPlotDone(event)
-+ return
-+
-+ if self.tasks_pids['set_data'] == event.pid:
-+ self.SetDataDone(event)
-+ return
++ from scatt_plot.dialogs import ScattPlotMainDialog
++ self.dialogs['scatt_plot'] = ScattPlotMainDialog(parent=self, giface=self._giface)
+
-+ if self.tasks_pids['set_edit_cat_data'] == event.pid:
-+ self.SetEditCatDataDone(event)
-+ return
++ self.dialogs['scatt_plot'].CenterOnScreen()
++ self.dialogs['scatt_plot'].Show()
+
-+ def EditCat(self, edit_type):
-+
-+ self.edit_cat_type = edit_type
-+
-+ if self.edit_cat_type:
-+ for scatt in self.scatt_plts.itervalues():
-+ scatt.StopCategoryEdit()
-+ scatt.StartCategoryEdit()
-+
-+ else:
-+ for scatt in self.scatt_plts.itervalues():
-+ scatt.StopCategoryEdit()
-+
-+ def SetEditCatData(self, scatt_id, bbox):
-+
-+ value = 1
-+ if self.edit_cat_type == 'remove':
-+ value = 0
-+
-+ self.tasks_pids['set_edit_cat_data'] = self.thread.GetId()
-+
-+ sel_cat_id = self.cats_mgr.GetSelectedCat()
-+
-+ self.thread.Run(callable = self.core.SetEditCatData,
-+ scatt_id = scatt_id,
-+ cat_id = sel_cat_id,
-+ bbox = bbox,
-+ value = value)
-+
-+ def SetEditCatDataDone(self, event):
-+
-+ self.RenderScattPlts()
-+
-+ cat_id = event.kwds["cat_id"]
-+
-+ cat_rast = self.core.GetCatRastOut(cat_id)
-+
-+
-+ if cat_rast not in self.added_cats_rasts.values():
-+
-+ cats_attrs = self.cats_mgr.GetCategoryAttrs(cat_id)
-+
-+ #TODO use standard raster lib
-+ name = "cat_%d" % cat_id
-+ ret, err_msg = RunCommand('r.external',
-+ output = name,
-+ getErrorMsg = True,
-+ input = cat_rast,
-+ flags = "o",
-+ overwrite = True)
-+
-+ if ret != 0:
-+ GError(_("r.external failed\n%s" % err_msg))
-+
-+ region = self.core.GetRegion()
-+ ret, err_msg = RunCommand('r.region',
-+ map = name,
-+ getErrorMsg = True,
-+ n = "%f" % region['n'],
-+ s = "%f" % region['s'],
-+ e = "%f" % region['e'],
-+ w = "%f" % region['w'],
-+ )
-+
-+ region = self.core.GetRegion()
-+ ret, err_msg = RunCommand('r.colors',
-+ map = name,
-+ rules = "-",
-+ stdin = "1 %s" % cats_attrs["color"],
-+ getErrorMsg = True)
-+
-+ if ret != 0:
-+ GError(_("r.region failed\n%s" % err_msg))
-+
-+ self.mapWin.Map.AddLayer(ltype = "raster", name = "cat_%d" % cat_id, render = True,
-+ command = ["d.rast", "map=%s" % name, "values=1"])
-+
-+ #elif self.giface.GetLayerTree():
-+ # self.giface.GetLayerTree().AddLayer("raster", lname = "cat_%d" % cat_id, lchecked = True,
-+ # lcmd = ["d.rast", "map=%s" % name, "values=1"])
-+
-+ if ret != 0:
-+ GError(_("r.region failed\n%s" % err_msg))
-+
-+ self.added_cats_rasts[cat_id] = cat_rast
-+
-+ self.giface.updateMap.emit()
-+
-+ def DigitDataChanged(self, vectMap, digit):
-+
-+ if self.mapWin_conn:
-+ self.mapWin_conn.DigitDataChanged(vectMap, digit)
-+ return 1
-+ else:
-+ return 0
-+
-+ def GetCategoriesManager(self):
-+ return self.cats_mgr
-+
-+class CategoriesManager:
-+
-+ def __init__(self, scatt_mgr, core):
-+
-+ self.core = core
-+ self.scatt_mgr = scatt_mgr
-+
-+ self.cats = {}
-+ self.cats_ids = []
-+
-+ self.sel_cat_id = -1
-+
-+ self.initialized = Signal('CategoriesManager.initialized')
-+ self.setCategoryAttrs = Signal('CategoriesManager.setCategoryAttrs')
-+ self.deletedCategory = Signal('CategoriesManager.deletedCategory')
-+ self.addedCategory = Signal('CategoriesManager.addedCategory')
-+
-+ def Clear(self):
-+
-+ self.cats.clear()
-+ del self.cats_ids[:]
-+
-+ self.sel_cat_id = -1
-+
-+ def InitCoreCats(self):
-+ if self.scatt_mgr.data_set:
-+ for cat_id in self.cats_ids:
-+ self.core.AddCategory(cat_id)
-+
-+ def AddCategory(self, cat_id = None, name = None, color = None):
-+
-+ if cat_id is None:
-+ if self.cats_ids:
-+ cat_id = max(self.cats_ids) + 1
-+ else:
-+ cat_id = 1
-+
-+ if self.scatt_mgr.data_set:
-+ ret = self.core.AddCategory(cat_id)
-+ if ret < 0: #TODO
-+ return -1;
-+
-+ self.cats[cat_id] = {
-+ 'name' : _('Category %s' % cat_id ),
-+ 'color' : "0:0:0"
-+ }
-+ self.cats_ids.append(cat_id)
-+
-+ if name is not None:
-+ self.cats[cat_id]["name"] = name
-+
-+ if color is not None:
-+ self.cats[cat_id]["color"] = color
-+
-+ self.addedCategory.emit(cat_id = cat_id,
-+ name = self.cats[cat_id]["name"],
-+ color = self.cats[cat_id]["color"] )
-+ return cat_id
-+
-+ def SetCategoryAttrs(self, cat_id, attrs_dict):
-+ for k, v in attrs_dict.iteritems():
-+ self.cats[cat_id][k] = v
-+
-+ self.setCategoryAttrs.emit(cat_id = cat_id, attrs_dict = attrs_dict)
-+
-+ def DeleteCategory(self, cat_id):
-+
-+ if self.scatt_mgr.data_set:
-+ self.core.DeleteCategory(cat_id)
-+ del self.cats[cat_id]
-+ self.cats_ids.remove(cat_id)
-+
-+ self.deletedCategory.emit(cat_id = cat_id)
-+
-+ #TODO emit event?
-+ def SetSelectedCat(self, cat_id):
-+ self.sel_cat_id = cat_id
-+
-+ def GetSelectedCat(self):
-+ return self.sel_cat_id
-+
-+ def GetCategoryAttrs(self, cat_id):
-+ #TODO is mutable
-+ return self.cats[cat_id]
-+
-+ def GetCategoriesAttrs(self):
-+ #TODO is mutable
-+ return self.cats
-+
-+ def GetCategories(self):
-+ return self.cats_ids[:]
-+
-+class MapWinConnection:
-+ def __init__(self, scatt_mgr, mapWin, scatt_rast_updater):
-+ self.mapWin = mapWin
-+ self.vectMap = None
-+ self.scatt_rast_updater = scatt_rast_updater
-+ self.scatt_mgr = scatt_mgr
-+ self.cats_mgr = scatt_mgr.cats_mgr
-+
-+ self.thread = self.scatt_mgr.thread
-+
-+ #TODO
-+ self.mapWin.parent.toolbars["vdigit"].editingStarted.connect(self.DigitDataChanged)
-+
-+ #def ChangeMap(self, vectMap, layers_cats):
-+ # self.vectMap = vectMap
-+ # self.layers_cats = layers_cats
-+
-+ #ret, region, msg = RunCommand("v.to.rast",
-+ # flags = "gp",
-+ # getErrorMsg = True,
-+ # read = True)
-+
-+ def _connectSignals(self):
-+ self.digit.featureAdded.connect(self.AddFeature)
-+ self.digit.areasDeleted.connect(self.DeleteAreas)
-+ self.digit.featuresDeleted.connect(self.DeleteAreas)
-+ self.digit.vertexMoved.connect(self.ChangeVertex)
-+ self.digit.vertexRemoved.connect(self.ChangeVertex)
-+ self.digit.lineEdited.connect(self.ChangeVertex)
-+ self.digit.featuresMoved.connect(self.MoveFeatures)
-+
-+ def AddFeature(self, new_geom, cat):
-+ if not self.scatt_mgr.data_set:
-+ return
-+
-+ self.scatt_mgr.tasks_pids['mapwin_conn'].append(self.thread.GetId())
-+ self.thread.Run(callable = self.scatt_rast_updater.AddedFeature,
-+ new_geom = new_geom,
-+ cat = cat)
-+
-+ def DeleteAreas(self, old_geoms, old_areas_cats):
-+ if not self.scatt_mgr.data_set:
-+ return
-+
-+ self.scatt_mgr.tasks_pids['mapwin_conn'].append(self.thread.GetId())
-+ self.thread.Run(callable = self.scatt_rast_updater.DeletedAreas,
-+ old_geoms = old_geoms,
-+ old_areas_cats = old_areas_cats)
-+
-+ def ChangeVertex(self, new_geom, new_areas_cats, old_geom, old_areas_cats):
-+ if not self.scatt_mgr.data_set:
-+ return
-+
-+ self.scatt_mgr.tasks_pids['mapwin_conn'].append(self.thread.GetId())
-+ self.thread.Run(callable = self.scatt_rast_updater.ChangedVertex,
-+ new_geom = new_geom,
-+ old_geom = old_geom,
-+ old_areas_cats = old_areas_cats,
-+ new_areas_cats = new_areas_cats)
-+
-+ def MoveFeatures(self, old_geoms, old_areas_cats, new_areas_cats, move):
-+ if not self.scatt_mgr.data_set:
-+ return
-+
-+ self.scatt_mgr.tasks_pids['mapwin_conn'].append(self.thread.GetId())
-+ self.thread.Run(callable = self.scatt_rast_updater.MovedFeatures,
-+ move = move,
-+ old_geoms = old_geoms,
-+ old_areas_cats = old_areas_cats,
-+ new_areas_cats = new_areas_cats)
-+
-+ def DigitDataChanged(self, vectMap, digit):
-+
-+ self.digit = digit
-+ self.vectMap = vectMap
-+
-+ self.scatt_rast_updater.SetVectMap(vectMap)
-+
-+ self._connectSignals()
-+
-+class IClassConnection:
-+ def __init__(self, scatt_mgr, iclass_frame, cats_mgr):
-+ self.iclass_frame = iclass_frame
-+ self.stats_data = self.iclass_frame.stats_data
-+ self.cats_mgr = cats_mgr
-+ self.scatt_mgr = scatt_mgr
-+
-+ self.stats_data.statisticsAdded.connect(self.AddCategory)
-+ self.stats_data.statisticsDeleted.connect(self.DeleteCategory)
-+ self.stats_data.allStatisticsDeleted.connect(self.DeletAllCategories)
-+ self.stats_data.statisticsSet.connect(self.SetCategory)
-+
-+ self.cats_mgr.setCategoryAttrs.connect(self.SetStatistics)
-+ self.cats_mgr.deletedCategory.connect(self.DeleteStatistics)
-+ self.cats_mgr.addedCategory.connect(self.AddStatistics)
-+
-+ self.SyncCats()
-+
-+ def SyncCats(self):
-+ self.cats_mgr.addedCategory.disconnect(self.AddStatistics)
-+ cats = self.stats_data.GetCategories()
-+ for c in cats:
-+ stats = self.stats_data.GetStatistics(c)
-+ self.cats_mgr.AddCategory(c, stats.name, stats.color)
-+ self.cats_mgr.addedCategory.connect(self.AddStatistics)
-+
-+ def AddCategory(self, cat, name, color):
-+ self.cats_mgr.addedCategory.disconnect(self.AddStatistics)
-+ self.cats_mgr.AddCategory(cat_id = cat, name = name, color = color)
-+ self.cats_mgr.addedCategory.connect(self.AddStatistics)
-+
-+ def DeleteCategory(self, cat):
-+ self.cats_mgr.deletedCategory.disconnect(self.DeleteStatistics)
-+ self.cats_mgr.DeleteCategory(cat)
-+ self.cats_mgr.deletedCategory.connect(self.DeleteStatistics)
-+
-+
-+ def DeletAllCategories(self):
-+
-+ self.cats_mgr.deletedCategory.disconnect(self.DeleteStatistics)
-+ cats = self.stats_data.GetCategories()
-+ for c in cats:
-+ self.cats_mgr.DeleteCategory(c)
-+ self.cats_mgr.deletedCategory.connect(self.DeleteStatistics)
-+
-+ def SetCategory(self, cat, stats):
-+
-+ self.cats_mgr.setCategoryAttrs.disconnect(self.SetStatistics)
-+ cats_attr = {}
-+ for attr in ['name', 'color']:
-+ if stats.has_key(attr):
-+ cats_attr[attr] = stats[attr]
-+
-+ if cats_attr:
-+ self.cats_mgr.SetCategoryAttrs(cat, cats_attr)
-+ self.cats_mgr.setCategoryAttrs.connect(self.SetStatistics)
-+
-+
-+ def SetStatistics(self, cat_id, attrs_dict):
-+ self.stats_data.statisticsSet.disconnect(self.SetCategory)
-+ self.stats_data.GetStatistics(cat_id).SetStatistics(attrs_dict)
-+ self.stats_data.statisticsSet.connect(self.SetCategory)
-+
-+ def AddStatistics(self, cat_id, name, color):
-+ self.stats_data.statisticsAdded.disconnect(self.AddCategory)
-+ self.stats_data.AddStatistics(cat_id, name, color)
-+ self.stats_data.statisticsAdded.connect(self.AddCategory)
-+
-+ def DeleteStatistics(self, cat_id):
-+ self.stats_data.statisticsDeleted.disconnect(self.DeleteCategory)
-+ self.stats_data.DeleteStatistics(cat_id)
-+ self.stats_data.statisticsDeleted.connect(self.DeleteCategory)
+ def OnVNet(self, event):
+ """!Dialog for v.net* modules
+ """
Index: gui/wxpython/vdigit/wxdigit.py
===================================================================
---- gui/wxpython/vdigit/wxdigit.py (revision 57285)
+--- gui/wxpython/vdigit/wxdigit.py (revision 57336)
+++ gui/wxpython/vdigit/wxdigit.py (working copy)
@@ -17,7 +17,7 @@
(and NumPy would be an excellent candidate for acceleration via
@@ -3006,7 +3160,7 @@
def GetLineCats(self, line):
Index: gui/wxpython/vdigit/toolbars.py
===================================================================
---- gui/wxpython/vdigit/toolbars.py (revision 57285)
+--- gui/wxpython/vdigit/toolbars.py (revision 57336)
+++ gui/wxpython/vdigit/toolbars.py (working copy)
@@ -17,6 +17,7 @@
import wx
@@ -3035,7 +3189,7 @@
def StopEditing(self):
Index: gui/wxpython/Makefile
===================================================================
---- gui/wxpython/Makefile (revision 57285)
+--- gui/wxpython/Makefile (revision 57336)
+++ gui/wxpython/Makefile (working copy)
@@ -13,7 +13,7 @@
$(wildcard animation/* core/*.py dbmgr/* gcp/*.py gmodeler/* \
@@ -3055,555 +3209,11 @@
DSTDIRS := $(patsubst %,$(ETCDIR)/%,icons scripts xml)
-Index: gui/wxpython/mapdisp/toolbars.py
-===================================================================
---- gui/wxpython/mapdisp/toolbars.py (revision 57285)
-+++ gui/wxpython/mapdisp/toolbars.py (working copy)
-@@ -243,7 +243,8 @@
- (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["scatter"], self.parent.OnScatterplot2)))
-
- def OnDecoration(self, event):
- """!Decorations overlay menu
-Index: gui/wxpython/mapdisp/frame.py
-===================================================================
---- gui/wxpython/mapdisp/frame.py (revision 57285)
-+++ gui/wxpython/mapdisp/frame.py (working copy)
-@@ -207,6 +207,7 @@
- #
- self.dialogs = {}
- self.dialogs['attributes'] = None
-+ self.dialogs['scatt_plot'] = None
- self.dialogs['category'] = None
- self.dialogs['barscale'] = None
- self.dialogs['legend'] = None
-@@ -1301,6 +1302,19 @@
- """!Returns toolbar with zooming tools"""
- return self.toolbars['map']
-
-+ def OnScatterplot2(self, event):
-+ """!Init interactive scatterplot tools
-+ """
-+ if self.dialogs['scatt_plot']:
-+ self.dialogs['scatt_plot'].Raise()
-+ return
-+
-+ from scatt_plot.dialogs import ScattPlotMainDialog
-+ self.dialogs['scatt_plot'] = ScattPlotMainDialog(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: lib/vector/vedit/move.c
-===================================================================
---- lib/vector/vedit/move.c (revision 57285)
-+++ lib/vector/vedit/move.c (working copy)
-@@ -22,13 +22,16 @@
- \param List list of primitives to be moved
- \param move_x,move_y,move_z direction (move_z used only if map is 3D)
- \param snap enable snapping (see globals.h)
--
-+ \param new_ids list of newly assigned ids for features, which vertexes were moved,
-+ new_id corresponds to same position of id in List
-+ null pointer can be passed
-+
- \return number of modified primitives
- \return -1 on error
- */
- int Vedit_move_lines(struct Map_info *Map, struct Map_info **BgMap,
- int nbgmaps, struct ilist *List, double move_x,
-- double move_y, double move_z, int snap, double thresh)
-+ double move_y, double move_z, int snap, double thresh, struct ilist *new_ids)
- {
- struct line_pnts *Points;
- struct line_cats *Cats;
-@@ -84,6 +87,8 @@
- if (newline < 0) {
- return -1;
- }
-+ if(new_ids)
-+ Vect_list_append(new_ids, newline);
-
- nlines_moved++;
- }
-Index: lib/vector/vedit/vertex.c
-===================================================================
---- lib/vector/vedit/vertex.c (revision 57285)
-+++ lib/vector/vedit/vertex.c (working copy)
-@@ -26,7 +26,10 @@
- \param move_x,move_y,move_z direction (move_z is used when map is 3D)
- \param move_first move only first vertex found in the bounding box
- \param snap snapping mode (see vedit.h)
--
-+ \param new_ids list of newly assigned ids for features, which vertexes were moved,
-+ new_id corresponds to same position of id in List
-+ if feature was not rewritten new id is -1
-+ null pointer can be passed
- \return number of moved verteces
- \return -1 on error
- */
-@@ -34,11 +37,11 @@
- int nbgmaps, struct ilist *List,
- struct line_pnts *coord, double thresh_coords,
- double thresh_snap, double move_x, double move_y,
-- double move_z, int move_first, int snap)
-+ double move_z, int move_first, int snap, struct ilist *new_ids)
- {
- int nvertices_moved, nlines_modified, nvertices_snapped;
-
-- int i, j, k;
-+ int i, j, k, newline;
- int line, type, rewrite;
- int npoints;
- double east, north, dist;
-@@ -159,12 +162,17 @@
- } /* for each coord */
-
- if (rewrite) {
-- if (Vect_rewrite_line(Map, line, type, Points, Cats) < 0) {
-+ newline = Vect_rewrite_line(Map, line, type, Points, Cats);
-+ if (newline < 0) {
- return -1;
- }
-+ if(new_ids)
-+ Vect_list_append(new_ids, newline);
-
- nlines_modified++;
- }
-+ else if(new_ids)
-+ Vect_list_append(new_ids, -1);
- } /* for each selected line */
-
- /* destroy structures */
-@@ -187,12 +195,15 @@
- \param List list of lines
- \param coord points location
- \param thresh find line in given threshold
--
-+ \param new_ids list of newly assigned ids for features, which vertexes were moved,
-+ new_id corresponds to same position of id in List
-+ if feature was not rewritten new id is -1
-+ null pointer can be passed
- \return number of add verteces
- \return -1 on error
- */
- int Vedit_add_vertex(struct Map_info *Map, struct ilist *List,
-- struct line_pnts *coord, double thresh)
-+ struct line_pnts *coord, double thresh, struct ilist *new_ids)
- {
- int i, j;
- int type, line, seg;
-@@ -200,6 +211,7 @@
- double east, north, dist;
- double *x, *y, *z;
- double px, py;
-+ int newline;
-
- struct line_pnts *Points;
- struct line_cats *Cats;
-@@ -253,12 +265,17 @@
- /* rewrite the line */
- if (rewrite) {
- Vect_line_prune(Points);
-- if (Vect_rewrite_line(Map, line, type, Points, Cats) < 0) {
-+ newline = Vect_rewrite_line(Map, line, type, Points, Cats);
-+ if (newline < 0) {
- return -1;
- }
-+ if(new_ids)
-+ Vect_list_append(new_ids, newline);
-
- nlines_modified++;
- }
-+ else if(new_ids)
-+ Vect_list_append(new_ids, -1);
- } /* for each line */
-
- /* destroy structures */
-@@ -277,12 +294,15 @@
- \param List list of selected lines
- \param coord points location
- \param thresh threshold value to find a line
--
-+ \param new_ids list of newly assigned ids for features, which vertexes were moved,
-+ new_id corresponds to same position of id in List
-+ if feature was not rewritten new id is -1
-+ null pointer can be passed
- \return number of removed vertices
- \return -1 on error
- */
- int Vedit_remove_vertex(struct Map_info *Map, struct ilist *List,
-- struct line_pnts *coord, double thresh)
-+ struct line_pnts *coord, double thresh, struct ilist *new_ids)
- {
- int i, j, k;
- int type, line;
-@@ -290,6 +310,7 @@
- double east, north;
- double dist;
- double *x, *y, *z;
-+ int newline;
-
- struct line_pnts *Points;
- struct line_cats *Cats;
-@@ -336,12 +357,18 @@
-
- if (rewrite) {
- /* rewrite the line */
-- if (Vect_rewrite_line(Map, line, type, Points, Cats) < 0) {
-+ newline = Vect_rewrite_line(Map, line, type, Points, Cats);
-+ if (newline < 0) {
- return -1;
- }
-+ if(new_ids)
-+ Vect_list_append(new_ids, newline);
-
- nlines_modified++;
- }
-+ else if(new_ids)
-+ Vect_list_append(new_ids, -1);
-+
- } /* for each line */
-
- /* destroy structures */
-Index: lib/imagery/scatt_sccats.c
-===================================================================
---- lib/imagery/scatt_sccats.c (revision 0)
-+++ lib/imagery/scatt_sccats.c (working copy)
-@@ -0,0 +1,321 @@
-+/*!
-+ \file lib/imagery/scatt_cat_rast.c
-+
-+ \brief Imagery library - functions for wx Scatter Plot Tool.
-+
-+ Low level functions used by wx 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 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>
-+
-+//TODO split formulas to be more understandable
-+static void id_scatt_to_bands(const int scatt_id, const int n_bands, int * band_1, int * band_2)
-+{
-+ int n_b1 = n_bands - 1;
-+
-+ * band_1 = (int) ((2 * n_b1 + 1 - sqrt((double)((2 * n_b1 + 1) * (2 * n_b1 + 1) - 8 * scatt_id))) / 2);
-+
-+ * band_2 = scatt_id - ((* band_1) * (2 * n_b1 + 1) - (* band_1) * (* band_1)) / 2 + (* band_1) + 1;
-+
-+ return;
-+}
-+
-+static void bands_to_id_scatt(const int band_1, const int band_2, const int n_bands, int * scatt_id)
-+{
-+ int n_b1 = n_bands - 1;
-+
-+ * scatt_id = (band_1 * (2 * n_b1 + 1) - band_1 * band_1) / 2 + band_2 - band_1 - 1;
-+
-+ return;
-+}
-+
-+void I_sc_init_cats(struct scCats * cats, int n_bands, int type)
-+{
-+ int i_cat;
-+
-+ cats->type = type;
-+
-+ cats->n_cats = 10;
-+ cats->n_a_cats = 0;
-+
-+ cats->n_bands = n_bands;
-+ cats->n_scatts = (n_bands - 1) * n_bands / 2;
-+
-+ cats->cats_arr = (struct scScatts **) malloc(cats->n_cats * sizeof(struct scScatts *));
-+ memset(cats->cats_arr, 0, cats-> n_cats * sizeof(struct scScatts *));
-+
-+ cats->cats_ids = (int *) malloc(cats->n_cats * sizeof(int));
-+ cats->cats_idxs =(int *) malloc(cats->n_cats * sizeof(int));
-+
-+ for(i_cat = 0; i_cat < cats->n_cats; i_cat++)
-+ cats->cats_idxs[i_cat] = -1;
-+
-+ return;
-+}
-+
-+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])
-+ {
-+ free(cats->cats_arr[i_cat]->scatt_idxs);
-+ free(cats->cats_arr[i_cat]->scatts_bands);
-+ free(cats->cats_arr[i_cat]->scatts_arr);
-+ free(cats->cats_arr[i_cat]);
-+ }
-+ }
-+
-+ free(cats->cats_ids);
-+ free(cats->cats_idxs);
-+ 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;
-+}
-+
-+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;
-+}
-+
-+int I_sc_add_cat(struct scCats * cats, int cat_id)
-+{
-+ int i_scatt;
-+ int n_a_cats = cats->n_a_cats;
-+
-+ if(cat_id < 0 || cat_id >= cats->n_cats)
-+ return -1;
-+
-+ if(cats->cats_idxs[cat_id] >= 0)
-+ return -1;
-+
-+ cats->cats_ids[n_a_cats] = cat_id;
-+ cats->cats_idxs[cat_id] = n_a_cats;
-+
-+ cats->cats_arr[n_a_cats] = (struct scScatts *) malloc(sizeof(struct scScatts));
-+
-+ cats->cats_arr[n_a_cats]->scatts_arr = (struct scdScattData **) 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 *) malloc(cats->n_scatts * 2 * sizeof(int));
-+
-+ cats->cats_arr[n_a_cats]->scatt_idxs = (int *) 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 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;
-+
-+ free(cats->cats_arr[cat_idx]->scatt_idxs);
-+ free(cats->cats_arr[cat_idx]->scatts_bands);
-+ free(cats->cats_arr[cat_idx]->scatts_arr);
-+ 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;
-+}
-+
-+
-+int I_sc_insert_scatt_data(struct scCats * cats, struct scdScattData * scatt_vals, 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_vals->b_conds_arr && cats->type == 1)
-+ return -1;
-+
-+ if(!scatt_vals->scatt_vals_arr && cats->type == 0)
-+ return -1;
-+
-+ n_a_scatts = scatts->n_a_scatts;
-+
-+ scatts->scatt_idxs[scatt_id] = n_a_scatts;
-+
-+ 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_vals;
-+ ++scatts->n_a_scatts;
-+
-+ return 0;
-+}
-+
-+int I_sc_remove_scatt_data(struct scCats * cats, struct scdScattData * scatt_vals, 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_vals = 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_vals = 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;
-+}
-+
-+void I_scd_init_scatt_data(struct scdScattData * scatt_vals, int n_vals, int type)
-+{
-+ scatt_vals->n_vals = n_vals;
-+
-+ if(type == 0)
-+ {
-+ scatt_vals->scatt_vals_arr = (unsigned int *) malloc(n_vals * sizeof(unsigned int));
-+ memset(scatt_vals->scatt_vals_arr, 0, n_vals * sizeof(unsigned int));
-+ scatt_vals->b_conds_arr = NULL;
-+ }
-+ else if(type == 1)
-+ {
-+ scatt_vals->b_conds_arr = (unsigned short *) malloc(n_vals * sizeof(unsigned short));
-+ memset(scatt_vals->b_conds_arr, 0, n_vals * sizeof(unsigned short));
-+ scatt_vals->scatt_vals_arr = NULL;
-+ }
-+
-+ return;
-+}
-+
-+void I_scd_free_scatt_data(struct scdScattData * scatt_vals)
-+{
-+
-+ free(scatt_vals->b_conds_arr);
-+ free(scatt_vals->scatt_vals_arr);
-+
-+ scatt_vals = NULL;
-+
-+ return;
-+}
-+
-+int I_scd_get_data_size(struct scdScattData * scatt_vals)
-+{
-+ return scatt_vals->n_vals;
-+}
-+
-+void * I_scd_get_data_ptr(struct scdScattData * scatt_vals)
-+{
-+ if(!scatt_vals->b_conds_arr)
-+ return scatt_vals->b_conds_arr;
-+ else if(!scatt_vals->scatt_vals_arr)
-+ return scatt_vals->scatt_vals_arr;
-+
-+ return NULL;
-+}
-+
-+int I_scd_set_value(struct scdScattData * scatt_vals, unsigned int val_idx, unsigned int val)
-+{
-+ if(val_idx < 0 && val_idx > scatt_vals->n_vals)
-+ return -1;
-+
-+ if(scatt_vals->b_conds_arr)
-+ scatt_vals->b_conds_arr[val_idx] = val;
-+ else if(scatt_vals->scatt_vals_arr)
-+ scatt_vals->scatt_vals_arr[val_idx] = val;
-+ else
-+ return -1;
-+
-+ return 0;
-+}
Index: lib/imagery/scatt.c
===================================================================
--- lib/imagery/scatt.c (revision 0)
+++ lib/imagery/scatt.c (working copy)
-@@ -0,0 +1,582 @@
+@@ -0,0 +1,610 @@
+/*!
+ \file lib/imagery/scatt.c
+
@@ -3837,22 +3447,31 @@
+
+static inline void update_cat_scatt_plt(CELL ** chunks, char ** null_chunks, int chunk_size, unsigned short * belongs_pix, struct scScatts * scatts)
+{
-+ int band_axis_1, band_axis_2, i_scatt, array_idx, cat_idx, i_chunks_pix;
-+ int r_bits = 256;
++ int band_axis_1, band_axis_2, i_scatt, array_idx, cat_idx, i_chunks_pix, max_arr_idx;
+
-+ CELL * band_1_chunks;
-+ CELL * band_2_chunks;
++ CELL * b_1_chunks;
++ CELL * b_2_chunks;
+ char * band_1_null_chunks,* band_2_null_chunks;
+
++ struct Range b_1_range, b_2_range;
++ int b_1_range_size;
++
+ int * scatts_bands = scatts->scatts_bands;
++
+ for(i_scatt = 0; i_scatt < scatts->n_a_scatts; i_scatt++)
+ {
-+ band_1_chunks = chunks[scatts_bands[i_scatt * 2]];
-+ band_2_chunks = chunks[scatts_bands[i_scatt * 2 + 1]];
++ b_1_chunks = chunks[scatts_bands[i_scatt * 2]];
++ b_2_chunks = chunks[scatts_bands[i_scatt * 2 + 1]];
+
+ band_1_null_chunks = null_chunks[scatts_bands[i_scatt * 2]];
+ band_2_null_chunks = null_chunks[scatts_bands[i_scatt * 2 + 1]];
+
++ b_1_range = scatts->scatts_arr[i_scatt]->band_1_range;
++ b_2_range = scatts->scatts_arr[i_scatt]->band_2_range;
++
++ b_1_range_size = b_1_range.max - b_1_range.min + 1;
++ max_arr_idx = (b_1_range.max - b_1_range.min + 1) * (b_2_range.max - b_2_range.min + 1);
++
+ for(i_chunks_pix = 0; i_chunks_pix < chunk_size; i_chunks_pix++)
+ {
+ if(!belongs_pix[i_chunks_pix] ||
@@ -3860,8 +3479,12 @@
+ band_2_null_chunks[i_chunks_pix] == 1)
+ continue;
+
-+ array_idx = band_1_chunks[i_chunks_pix] + band_2_chunks[i_chunks_pix] * r_bits;
++ array_idx = b_1_chunks[i_chunks_pix] - b_1_range.min + (b_2_chunks[i_chunks_pix] - b_2_range.min) * b_1_range_size;
+
++ if(array_idx < 0 || array_idx >= max_arr_idx) {
++ G_warning ("pixel out of range");
++ continue;
++ }
+ ++scatts->scatts_arr[i_scatt]->scatt_vals_arr[array_idx];
+ }
+ }
@@ -3873,21 +3496,22 @@
+{
+
+ int i_chunks_pix, i_cat, i_scatt, n_a_scatts, i_cond;
-+ int cat_id, scatt_plts_cat_idx, array_idx;
++ int cat_id, scatt_plts_cat_idx, array_idx, max_arr_idx;
+ char * band_1_null_chunks,* band_2_null_chunks;
+
-+ int r_bits = 256;
-+
+ struct scScatts * scatts_conds;
+ struct scScatts * scatt_plts_scatts;
+ struct scdScattData * conds;
+
++ struct Range b_1_range, b_2_range;
++ int b_1_range_size;
++
+ int * scatts_bands;
+ struct scdScattData ** scatts_arr;
+
-+ CELL * band_1_chunks;
-+ CELL * band_2_chunks;
-+ unsigned int * i_scatt_conds;
++ CELL * b_1_chunks;
++ CELL * b_2_chunks;
++ unsigned char * i_scatt_conds;
+
+ unsigned short * belongs_pix = (unsigned short *) G_malloc(chunk_size * sizeof(unsigned short));
+ unsigned char * rast_pixs = (unsigned char *) G_malloc(chunk_size * sizeof(unsigned char));
@@ -3936,14 +3560,22 @@
+ // test every defined conditions in scatter plots
+ for(i_scatt = 0; i_scatt < scatts_conds->n_a_scatts; i_scatt++)
+ {
-+ band_1_chunks = chunks[scatts_bands[i_scatt * 2]];
-+ band_2_chunks = chunks[scatts_bands[i_scatt * 2 + 1]];
++ b_1_chunks = chunks[scatts_bands[i_scatt * 2]];
++ b_2_chunks = chunks[scatts_bands[i_scatt * 2 + 1]];
+
+ band_1_null_chunks = null_chunks[scatts_bands[i_scatt * 2]];
+ band_2_null_chunks = null_chunks[scatts_bands[i_scatt * 2 + 1]];
+
+ i_scatt_conds = scatts_conds->scatts_arr[i_scatt]->b_conds_arr;
+
++ b_1_range = scatts_conds->scatts_arr[i_scatt]->band_1_range;
++ b_2_range = scatts_conds->scatts_arr[i_scatt]->band_2_range;
++
++ b_1_range_size = b_1_range.max - b_1_range.min + 1;
++
++ max_arr_idx = (b_1_range.max - b_1_range.min + 1) * (b_2_range.max - b_2_range.min + 1);
++ //G_message("max_arr_idx scatt_conds: %d", max_arr_idx);
++
+ for(i_chunks_pix = 0; i_chunks_pix < chunk_size; i_chunks_pix++)
+ {
+ if(belongs_pix[i_chunks_pix] ||
@@ -3951,7 +3583,13 @@
+ band_2_null_chunks[i_chunks_pix] == 1)
+ continue;
+
-+ if(i_scatt_conds[band_1_chunks[i_chunks_pix] + band_2_chunks[i_chunks_pix] * r_bits])
++ array_idx = b_1_chunks[i_chunks_pix] - b_1_range.min + (b_2_chunks[i_chunks_pix] - b_2_range.min) * b_1_range_size;
++ /*TODO test value */
++ if(array_idx < 0 || array_idx >= max_arr_idx) {
++ G_warning ("pixel out of range");
++ continue;
++ }
++ if(i_scatt_conds[array_idx])
+ belongs_pix[i_chunks_pix] = 1;
+ }
+ }
@@ -4187,3 +3825,522 @@
+ return 0;
+}
\ No newline at end of file
+Index: lib/imagery/scatt_sccats.c
+===================================================================
+--- lib/imagery/scatt_sccats.c (revision 0)
++++ lib/imagery/scatt_sccats.c (working copy)
+@@ -0,0 +1,342 @@
++/*!
++ \file lib/imagery/scatt_cat_rast.c
++
++ \brief Imagery library - functions for wx Scatter Plot Tool.
++
++ Low level functions used by wx 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 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>
++
++//TODO split formulas to be more understandable
++static void id_scatt_to_bands(const int scatt_id, const int n_bands, int * band_1, int * band_2)
++{
++ int n_b1 = n_bands - 1;
++
++ * band_1 = (int) ((2 * n_b1 + 1 - sqrt((double)((2 * n_b1 + 1) * (2 * n_b1 + 1) - 8 * scatt_id))) / 2);
++
++ * band_2 = scatt_id - ((* band_1) * (2 * n_b1 + 1) - (* band_1) * (* band_1)) / 2 + (* band_1) + 1;
++
++ return;
++}
++
++static void bands_to_id_scatt(const int band_1, const int band_2, const int n_bands, int * scatt_id)
++{
++ int n_b1 = n_bands - 1;
++
++ * scatt_id = (band_1 * (2 * n_b1 + 1) - band_1 * band_1) / 2 + band_2 - band_1 - 1;
++
++ return;
++}
++
++void I_sc_init_cats(struct scCats * cats, int n_bands, int type)
++{
++ int i_cat;
++
++ cats->type = type;
++
++ cats->n_cats = 10;
++ cats->n_a_cats = 0;
++
++ cats->n_bands = n_bands;
++ cats->n_scatts = (n_bands - 1) * n_bands / 2;
++
++ cats->cats_arr = (struct scScatts **) malloc(cats->n_cats * sizeof(struct scScatts *));
++ memset(cats->cats_arr, 0, cats-> n_cats * sizeof(struct scScatts *));
++
++ cats->cats_ids = (int *) malloc(cats->n_cats * sizeof(int));
++ cats->cats_idxs =(int *) malloc(cats->n_cats * sizeof(int));
++
++ for(i_cat = 0; i_cat < cats->n_cats; i_cat++)
++ cats->cats_idxs[i_cat] = -1;
++
++ return;
++}
++
++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])
++ {
++ free(cats->cats_arr[i_cat]->scatt_idxs);
++ free(cats->cats_arr[i_cat]->scatts_bands);
++ free(cats->cats_arr[i_cat]->scatts_arr);
++ free(cats->cats_arr[i_cat]);
++ }
++ }
++
++ free(cats->cats_ids);
++ free(cats->cats_idxs);
++ 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;
++}
++
++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;
++}
++
++int I_sc_add_cat(struct scCats * cats, int cat_id)
++{
++ int i_scatt;
++ int n_a_cats = cats->n_a_cats;
++
++ if(cat_id < 0 || cat_id >= cats->n_cats)
++ return -1;
++
++ if(cats->cats_idxs[cat_id] >= 0)
++ return -1;
++
++ cats->cats_ids[n_a_cats] = cat_id;
++ cats->cats_idxs[cat_id] = n_a_cats;
++
++ cats->cats_arr[n_a_cats] = (struct scScatts *) malloc(sizeof(struct scScatts));
++
++ cats->cats_arr[n_a_cats]->scatts_arr = (struct scdScattData **) 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 *) malloc(cats->n_scatts * 2 * sizeof(int));
++
++ cats->cats_arr[n_a_cats]->scatt_idxs = (int *) 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 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;
++
++ free(cats->cats_arr[cat_idx]->scatt_idxs);
++ free(cats->cats_arr[cat_idx]->scatts_bands);
++ free(cats->cats_arr[cat_idx]->scatts_arr);
++ 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;
++}
++
++
++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;
++
++ 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;
++}
++
++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;
++}
++
++void I_scd_init_scatt_data(struct scdScattData * scatt_data, int type, int n_vals, void * data,
++ struct Range band_1_range, struct Range band_2_range)
++{
++ scatt_data->n_vals = n_vals;
++
++ scatt_data->band_1_range.min = band_1_range.min;
++ scatt_data->band_1_range.max = band_1_range.max;
++ scatt_data->band_1_range.first_time = 0;
++
++ scatt_data->band_2_range.min = band_2_range.min;
++ scatt_data->band_2_range.max = band_2_range.max;
++ scatt_data->band_2_range.first_time = 0;
++
++ if(type == SC_SCATT_DATA)
++ {
++ if(data)
++ scatt_data->scatt_vals_arr = (unsigned int *) data;
++ else {
++ scatt_data->scatt_vals_arr = (unsigned int *) 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 *) 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;
++}
++
++void I_scd_free_scatt_data(struct scdScattData * scatt_data)
++{
++
++ free(scatt_data->b_conds_arr);
++ free(scatt_data->scatt_vals_arr);
++
++ scatt_data = NULL;
++
++ return;
++}
++
++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;
++}
++
++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;
++}
+Index: lib/vector/vedit/move.c
+===================================================================
+--- lib/vector/vedit/move.c (revision 57336)
++++ lib/vector/vedit/move.c (working copy)
+@@ -22,13 +22,16 @@
+ \param List list of primitives to be moved
+ \param move_x,move_y,move_z direction (move_z used only if map is 3D)
+ \param snap enable snapping (see globals.h)
+-
++ \param new_ids list of newly assigned ids for features, which vertexes were moved,
++ new_id corresponds to same position of id in List
++ null pointer can be passed
++
+ \return number of modified primitives
+ \return -1 on error
+ */
+ int Vedit_move_lines(struct Map_info *Map, struct Map_info **BgMap,
+ int nbgmaps, struct ilist *List, double move_x,
+- double move_y, double move_z, int snap, double thresh)
++ double move_y, double move_z, int snap, double thresh, struct ilist *new_ids)
+ {
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+@@ -84,6 +87,8 @@
+ if (newline < 0) {
+ return -1;
+ }
++ if(new_ids)
++ Vect_list_append(new_ids, newline);
+
+ nlines_moved++;
+ }
+Index: lib/vector/vedit/vertex.c
+===================================================================
+--- lib/vector/vedit/vertex.c (revision 57336)
++++ lib/vector/vedit/vertex.c (working copy)
+@@ -26,7 +26,10 @@
+ \param move_x,move_y,move_z direction (move_z is used when map is 3D)
+ \param move_first move only first vertex found in the bounding box
+ \param snap snapping mode (see vedit.h)
+-
++ \param new_ids list of newly assigned ids for features, which vertexes were moved,
++ new_id corresponds to same position of id in List
++ if feature was not rewritten new id is -1
++ null pointer can be passed
+ \return number of moved verteces
+ \return -1 on error
+ */
+@@ -34,11 +37,11 @@
+ int nbgmaps, struct ilist *List,
+ struct line_pnts *coord, double thresh_coords,
+ double thresh_snap, double move_x, double move_y,
+- double move_z, int move_first, int snap)
++ double move_z, int move_first, int snap, struct ilist *new_ids)
+ {
+ int nvertices_moved, nlines_modified, nvertices_snapped;
+
+- int i, j, k;
++ int i, j, k, newline;
+ int line, type, rewrite;
+ int npoints;
+ double east, north, dist;
+@@ -159,12 +162,17 @@
+ } /* for each coord */
+
+ if (rewrite) {
+- if (Vect_rewrite_line(Map, line, type, Points, Cats) < 0) {
++ newline = Vect_rewrite_line(Map, line, type, Points, Cats);
++ if (newline < 0) {
+ return -1;
+ }
++ if(new_ids)
++ Vect_list_append(new_ids, newline);
+
+ nlines_modified++;
+ }
++ else if(new_ids)
++ Vect_list_append(new_ids, -1);
+ } /* for each selected line */
+
+ /* destroy structures */
+@@ -187,12 +195,15 @@
+ \param List list of lines
+ \param coord points location
+ \param thresh find line in given threshold
+-
++ \param new_ids list of newly assigned ids for features, which vertexes were moved,
++ new_id corresponds to same position of id in List
++ if feature was not rewritten new id is -1
++ null pointer can be passed
+ \return number of add verteces
+ \return -1 on error
+ */
+ int Vedit_add_vertex(struct Map_info *Map, struct ilist *List,
+- struct line_pnts *coord, double thresh)
++ struct line_pnts *coord, double thresh, struct ilist *new_ids)
+ {
+ int i, j;
+ int type, line, seg;
+@@ -200,6 +211,7 @@
+ double east, north, dist;
+ double *x, *y, *z;
+ double px, py;
++ int newline;
+
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+@@ -253,12 +265,17 @@
+ /* rewrite the line */
+ if (rewrite) {
+ Vect_line_prune(Points);
+- if (Vect_rewrite_line(Map, line, type, Points, Cats) < 0) {
++ newline = Vect_rewrite_line(Map, line, type, Points, Cats);
++ if (newline < 0) {
+ return -1;
+ }
++ if(new_ids)
++ Vect_list_append(new_ids, newline);
+
+ nlines_modified++;
+ }
++ else if(new_ids)
++ Vect_list_append(new_ids, -1);
+ } /* for each line */
+
+ /* destroy structures */
+@@ -277,12 +294,15 @@
+ \param List list of selected lines
+ \param coord points location
+ \param thresh threshold value to find a line
+-
++ \param new_ids list of newly assigned ids for features, which vertexes were moved,
++ new_id corresponds to same position of id in List
++ if feature was not rewritten new id is -1
++ null pointer can be passed
+ \return number of removed vertices
+ \return -1 on error
+ */
+ int Vedit_remove_vertex(struct Map_info *Map, struct ilist *List,
+- struct line_pnts *coord, double thresh)
++ struct line_pnts *coord, double thresh, struct ilist *new_ids)
+ {
+ int i, j, k;
+ int type, line;
+@@ -290,6 +310,7 @@
+ double east, north;
+ double dist;
+ double *x, *y, *z;
++ int newline;
+
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+@@ -336,12 +357,18 @@
+
+ if (rewrite) {
+ /* rewrite the line */
+- if (Vect_rewrite_line(Map, line, type, Points, Cats) < 0) {
++ newline = Vect_rewrite_line(Map, line, type, Points, Cats);
++ if (newline < 0) {
+ return -1;
+ }
++ if(new_ids)
++ Vect_list_append(new_ids, newline);
+
+ nlines_modified++;
+ }
++ else if(new_ids)
++ Vect_list_append(new_ids, -1);
++
+ } /* for each line */
+
+ /* destroy structures */
More information about the grass-commit
mailing list