[GRASS-SVN] r57458 - sandbox/turek/scatter_plot

svn_grass at osgeo.org svn_grass at osgeo.org
Sat Aug 17 05:13:56 PDT 2013


Author: turek
Date: 2013-08-17 05:13:56 -0700 (Sat, 17 Aug 2013)
New Revision: 57458

Modified:
   sandbox/turek/scatter_plot/testing_patch.diff
Log:
beter plots manipulation, bugsfixing

Modified: sandbox/turek/scatter_plot/testing_patch.diff
===================================================================
--- sandbox/turek/scatter_plot/testing_patch.diff	2013-08-16 13:46:07 UTC (rev 57457)
+++ sandbox/turek/scatter_plot/testing_patch.diff	2013-08-17 12:13:56 UTC (rev 57458)
@@ -1,19 +1,6 @@
-Index: include/defs/vedit.h
-===================================================================
---- include/defs/vedit.h	(revision 57453)
-+++ include/defs/vedit.h	(working copy)
-@@ -33,6 +33,8 @@
- int Vedit_merge_lines(struct Map_info *, struct ilist *);
- 
- /* move.c */
-+int Vedit_move_areas(struct Map_info *, struct Map_info **, int,
-+		     		 struct ilist *, double, double, double, int, double);
- int Vedit_move_lines(struct Map_info *, struct Map_info **, int,
- 		     struct ilist *, double, double, double, int, double);
- 
 Index: include/defs/imagery.h
 ===================================================================
---- include/defs/imagery.h	(revision 57453)
+--- include/defs/imagery.h	(revision 57457)
 +++ include/defs/imagery.h	(working copy)
 @@ -110,6 +110,23 @@
  FILE *I_fopen_subgroup_ref_new(const char *, const char *);
@@ -39,9 +26,22 @@
  /* 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 57457)
++++ include/defs/vedit.h	(working copy)
+@@ -33,6 +33,8 @@
+ int Vedit_merge_lines(struct Map_info *, struct ilist *);
+ 
+ /* move.c */
++int Vedit_move_areas(struct Map_info *, struct Map_info **, int,
++		     		 struct ilist *, double, double, double, int, double);
+ int Vedit_move_lines(struct Map_info *, struct Map_info **, int,
+ 		     struct ilist *, double, double, double, int, double);
+ 
 Index: include/imagery.h
 ===================================================================
---- include/imagery.h	(revision 57453)
+--- include/imagery.h	(revision 57457)
 +++ include/imagery.h	(working copy)
 @@ -135,6 +135,55 @@
      
@@ -103,7 +103,7 @@
 ===================================================================
 --- gui/wxpython/scatt_plot/core_c.py	(revision 0)
 +++ gui/wxpython/scatt_plot/core_c.py	(working copy)
-@@ -0,0 +1,167 @@
+@@ -0,0 +1,166 @@
 +"""!
 + at package scatt_plot.scatt_plot
 +
@@ -132,10 +132,10 @@
 +from core.gcmd import GException
 +
 +
-+def ComputeScatts(region, scatt_conds, bands, n_bands, scatts, cats_rasts_in, cats_rasts_out):
++def ComputeScatts(region, scatt_conds, bands, n_bands, scatts, cats_rasts_conds, cats_rasts):
 +    q = Queue()
 +    p = Process(target=_computeScattsProcess, args=(region, scatt_conds, bands, 
-+                                                    n_bands, scatts, cats_rasts_in, cats_rasts_out, q))
++                                                    n_bands, scatts, cats_rasts_conds, cats_rasts, q))
 +    p.start()
 +    ret = q.get()
 +    p.join()
@@ -152,29 +152,26 @@
 +    return ret
 +
 +def CreateCatRast(region, cat_rast):
-+
 +    cell_head = _regionToCellHead(region)
 +    I_create_cat_rast(pointer(cell_head), cat_rast)   
 +
-+def _computeScattsProcess(region, scatt_conds, bands, n_bands, scatts, cats_rasts_in, cats_rasts_out, output_queue):
++def _computeScattsProcess(region, scatt_conds, bands, n_bands, scatts, cats_rasts_conds, cats_rasts, output_queue):
 +
 +    #TODO names for types not 0 and 1?
-+    sccats_c, refs = _getComputationStruct(scatts, 0, n_bands)
-+    scatt_conds_c, refs2 = _getComputationStruct(scatt_conds, 1, n_bands)
++    sccats_c, cats_rasts_c, refs = _getComputationStruct(scatts, cats_rasts, 0, n_bands)
++    scatt_conds_c, cats_rasts_conds_c, refs2 = _getComputationStruct(scatt_conds, cats_rasts_conds, 1, n_bands)
 +
 +    char_bands = _stringListToCharArr(bands)
-+    char_cats_rasts_out = _stringListToCharArr(cats_rasts_out)
-+    char_cats_rasts_in = _stringListToCharArr(cats_rasts_in)
-+
++   
 +    cell_head = _regionToCellHead(region)
 +
 +    ret = I_compute_scatts(pointer(cell_head),
 +                           pointer(scatt_conds_c),
-+                           pointer(char_cats_rasts_in),
++                           pointer(cats_rasts_conds_c),
 +                           pointer(char_bands),
 +                           n_bands,
 +                           pointer(sccats_c),
-+                           pointer(char_cats_rasts_out))
++                           pointer(cats_rasts_c))
 +
 +    I_sc_free_cats(pointer(sccats_c))
 +    I_sc_free_cats(pointer(scatt_conds_c))
@@ -189,7 +186,6 @@
 +
 +    return band_c_range
 +
-+
 +def _regionToCellHead(region):
 +    cell_head = struct_Cell_head()
 +    G_get_window(pointer(cell_head))
@@ -224,19 +220,20 @@
 +
 +    return char_arr
 +
-+def _getComputationStruct(cats, cats_type, n_bands):
++def _getComputationStruct(cats, cats_rasts, cats_type, n_bands):
 +
 +    sccats = struct_scCats()
 +    I_sc_init_cats(pointer(sccats), c_int(n_bands), c_int(cats_type));
-+        
-+    refs = []
++
++    refs = []        
++    cats_rasts_core = []
++    
 +    for cat_id, scatt_ids in cats.iteritems():
 +        cat_c_id = I_sc_add_cat(pointer(sccats))
++        cats_rasts_core.append(cats_rasts[cat_id])
 +
 +        for scatt_id, dt in scatt_ids.iteritems():
 +            # 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']
 +
 +                scatt_vals = scdScattData()
@@ -258,8 +255,10 @@
 +                                       pointer(scatt_vals),
 +                                       cat_c_id, scatt_id)
 +
-+    return sccats, refs
++    cats_rasts_c = _stringListToCharArr(cats_rasts_core)
 +
++    return sccats, cats_rasts_c, refs
++
 +def _updateCatRastProcess(patch_rast, region, cat_rast, output_queue):
 +    cell_head = _regionToCellHead(region)
 +    
@@ -289,7 +288,7 @@
 ===================================================================
 --- gui/wxpython/scatt_plot/plots.py	(revision 0)
 +++ gui/wxpython/scatt_plot/plots.py	(working copy)
-@@ -0,0 +1,223 @@
+@@ -0,0 +1,285 @@
 +"""!
 + at package scatt_plot.dialogs
 +
@@ -318,6 +317,7 @@
 +    NavigationToolbar2WxAgg as NavigationToolbar
 +except ImportError:
 +    haveMatPlot = False
++from grass.pydispatch.signal import Signal
 +
 +class ScatterPlotWidget(wx.Panel):
 +    def __init__(self, parent, scatt_id, scatt_mgr,
@@ -326,6 +326,7 @@
 +        wx.Panel.__init__(self, parent, id)
 +
 +        self.parent = parent
++        self.full_extend = None
 +
 +        self._createWidgets()
 +        self._doLayout()
@@ -339,11 +340,22 @@
 +        self.SetSize((200, 100))
 +        self.Layout()
 +
++        self.base_scale = 2.0
++        self.Bind(wx.EVT_CLOSE,lambda event : self.CleanUp())
++        self.plotClosed = Signal("ScatterPlotWidget.plotClosed")
++
++        self.contex_menu = ScatterPlotContextMenu(plot = self)
++
++    def ZoomToExtend(self):
++        if self.full_extend:
++            self.axes.axis(self.full_extend)
++            self.canvas.draw()
++
 +    def SetMode(self, mode):
 +        self._deactivateMode()
 +
 +        if mode == 'zoom':
-+            self.toolbar.zoom()
++            self.canvas.mpl_connect('scroll_event', self.zoom)
 +        elif mode == 'pan':
 +            self.toolbar.pan()
 +        elif mode in ["add", "remove"]:
@@ -354,12 +366,11 @@
 +        if self.toolbar._active == "PAN":
 +            self.toolbar.pan()
 +        elif self.toolbar._active == "ZOOM":
-+            self.toolbar.zoom()
++            self.canvas.mpl_disconnect(self.ciddscroll)
 +
 +        self._stopCategoryEdit()
 +
 +    def _startCategoryEdit(self):
-+        'connect to all the events we need'
 +        self.cidpress = self.canvas.mpl_connect(
 +            'button_press_event', self.OnPress)
 +        self.cidrelease = self.canvas.mpl_connect(
@@ -465,25 +476,29 @@
 +
 +            masked_cat = np.ma.masked_less_equal(scatt['np_vals'], 0)
 +
-+
 +            b1_i = scatt['bands_info']['b1']
 +            b2_i = scatt['bands_info']['b2']
++
++            self.full_extend = (b1_i['min'] - 0.5, b1_i['max'] + 0.5, b2_i['min'] - 0.5, b2_i['max'] + 0.5) 
 +            
 +            #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',
-+                                               aspect = "auto")
-+            
++            self.axes.imshow(masked_cat, cmap = cmap,
++                                         origin = 'lower',
++                                         extent = self.full_extend, 
++                                         interpolation='nearest',
++                                         aspect = "auto")
 +            self.canvas.draw()
 +
-+    
++
++        #xy = np.array([[0, 0], [10, 10], [20, 0]])
++        #pol = matplotlib.patches.Polygon(xy, closed=True, color = "g")
++        #self.axes.add_patch(pol)
++        
++
 +    def on_pick(self, event):
 +        pass
 +        # The event received here is of the type
@@ -504,21 +519,67 @@
 +
 +        #dlg.ShowModal() 
 +        #dlg.Destroy()        
-+
-+    def on_exit(self, event):
-+            
-+        self.CleanUp()
 +        
 +    def CleanUp(self):
++        self.plotClosed.emit(scatt_id = self.scatt_id)
++        self.Destroy()
++
++    def zoom(self, event):
++        # get the current x and y limits
++
++        cur_xlim = self.axes.get_xlim()
++        cur_ylim = self.axes.get_ylim()
++        cur_xrange = (cur_xlim[1] - cur_xlim[0])*.5
++        cur_yrange = (cur_ylim[1] - cur_ylim[0])*.5
++        xdata = event.xdata
++        ydata = event.ydata 
++        if event.button == 'up':
++            scale_factor = 1/self.base_scale
++        elif event.button == 'down':
++            scale_factor = self.base_scale
++        else:
++            scale_factor = 1
++
++        self.axes.set_xlim([xdata - cur_xrange*scale_factor,
++                           xdata + cur_xrange*scale_factor])
++        self.axes.set_ylim([ydata - cur_yrange*scale_factor,
++                            ydata + cur_yrange*scale_factor])
 +        
-+        self.parent.OnPlotClosed(self.scatt_id)
-+        self.Destroy()
++        self.canvas.draw() 
++
++
++class ScatterPlotContextMenu:
++    def __init__(self, plot):
++
++        self.plot = plot
++        self.canvas = plot.canvas
++        self.cidpress = self.canvas.mpl_connect(
++            'button_press_event', self.ContexMenu)
++   
++    def ContexMenu(self, event):
++
++        if event.button == 3 and event.inaxes:
++
++            menu = wx.Menu()       
++            menu_items = [["zoom_to_extend", _("Zoom to scatter plot extend"), lambda event : self.plot.ZoomToExtend()]]
++
++            for item in menu_items:
++                item_id = wx.ID_ANY
++                menu.Append(item_id, text = item[1])
++                menu.Bind(wx.EVT_MENU, item[2], id = item_id)
++
++            wx.CallAfter(self.ShowMenu, menu) 
++   
++    def ShowMenu(self, menu):
++
++        self.plot.PopupMenu(menu)
++        menu.Destroy()
 \ No newline at end of file
 Index: gui/wxpython/scatt_plot/controllers.py
 ===================================================================
 --- gui/wxpython/scatt_plot/controllers.py	(revision 0)
 +++ gui/wxpython/scatt_plot/controllers.py	(working copy)
-@@ -0,0 +1,563 @@
+@@ -0,0 +1,566 @@
 +"""!
 + at package scatt_plot.controllers
 +
@@ -539,7 +600,7 @@
 +#TODO
 +import wx
 +
-+from core.gcmd import GException, GError, RunCommand
++from core.gcmd import GException, GError, GMessage, RunCommand
 +
 +from scatt_plot.sc_pl_core import Core, idBandsToidScatt
 +from scatt_plot.plots import haveMatPlot
@@ -575,7 +636,7 @@
 +
 +        self.thread = gThread(self);
 +        
-+        self.scatt_plts = {}
++        self.plots = {}
 +        self.added_cats_rasts = {}
 +
 +        self.cats_to_update = []
@@ -612,9 +673,6 @@
 +
 +        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
@@ -646,6 +704,9 @@
 +        dlg.Destroy()
 +
 +    def _addScattPlot(self, scatt_id):
++        if self.plots.has_key(scatt_id):
++            GMessage(_("Scatter plot has been already added."))
++            return
 +
 +        self.tasks_pids['add_scatt'].append(self.thread.GetId())
 +        
@@ -654,36 +715,38 @@
 +    def RenderScattPlts(self):
 +
 +        cats_attrs = self.cats_mgr.GetCategoriesAttrs()
-+        for scatt_id, scatt in self.scatt_plts.iteritems():
++        for scatt_id, scatt in self.plots.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)
++        self.plots[scatt_id] = self.guiparent.NewScatterPlot(scatt_id = scatt_id)
++        self.plots[scatt_id].plotClosed.connect(self.PlotClosed)
 +
 +        if self.plot_mode:
-+            self.scatt_plts[scatt_id].SetMode(self.plot_mode)
++            self.plots[scatt_id].SetMode(self.plot_mode)
 +
 +        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()
++        self.plots[scatt_id].Plot(scatt_dt, cats_attrs)
++        self.plots[scatt_id].GetParent().Show()
 +
++    def PlotClosed(self, scatt_id):
++        print scatt_id
++        del self.plots[scatt_id]
++
 +    def CleanUp(self):
 +        self.core.CleanUp()
 +
-+        for scatt_id, scatt in self.scatt_plts.items():
++        for scatt_id, scatt in self.plots.items():
 +            scatt.CleanUp()
-+            del self.scatt_plts[scatt_id]
++            del self.plots[scatt_id]
 +
 +    def OnThreadDone(self, event):
 +        
@@ -733,7 +796,7 @@
 +
 +        self.plot_mode = mode
 +
-+        for scatt in self.scatt_plts.itervalues():
++        for scatt in self.plots.itervalues():
 +            scatt.SetMode(mode)
 +
 +    def SetEditCatData(self, scatt_id, bbox):
@@ -775,7 +838,6 @@
 +
 +        cat_rast = self.core.GetCatRast(cat_id)
 +
-+
 +        if cat_rast not in self.added_cats_rasts.values():
 +
 +            cats_attrs = self.cats_mgr.GetCategoryAttrs(cat_id)
@@ -791,7 +853,6 @@
 +                                      w = "%f" % region['w'],
 +                                      )
 +
-+            region = self.core.GetRegion()
 +            ret, err_msg = RunCommand('r.colors',
 +                                      map = cat_rast,
 +                                      rules = "-",
@@ -985,10 +1046,13 @@
 +        self.digit = digit
 +        self.vectMap = vectMap
 +
++        self.digit.EmitSignals(emit = True)
++
 +        self.scatt_rast_updater.SetVectMap(vectMap)
 +
 +        self._connectSignals()
 +
++
 +class IClassConnection:
 +    def __init__(self, scatt_mgr, iclass_frame, cats_mgr):
 +        self.iclass_frame = iclass_frame
@@ -1087,7 +1151,7 @@
 ===================================================================
 --- gui/wxpython/scatt_plot/sc_pl_core.py	(revision 0)
 +++ gui/wxpython/scatt_plot/sc_pl_core.py	(working copy)
-@@ -0,0 +1,627 @@
+@@ -0,0 +1,632 @@
 +"""!
 + at package scatt_plot.scatt_plot
 +
@@ -1287,16 +1351,21 @@
 +    def _rasterize(self, grass_region, layer, cat, out_rast):
 +
 +        #TODO different thread may be problem when user edits map
++        environs = os.environ.copy()
++        environs['GRASS_VECTOR_TEMPORARY'] = '1'
++
 +        ret, text, msg = RunCommand("v.build",
 +                                      map = self.vectMap,
 +                                      getErrorMsg = True,
-+                                      read = True)
++                                      read = True,
++                                      env = environs)
++
 +        if ret != 0:
 +            GException(_("v.build failed:\n%s" % msg))
 +
-+        #TODO thread problem with env variable remove it!!!!
 +        environs = os.environ.copy()
 +        environs["GRASS_REGION"] = grass_region["GRASS_REGION"]
++        environs['GRASS_VECTOR_TEMPORARY'] = '1'
 +
 +        ret, text, msg = RunCommand("v.to.rast",
 +                                    input = self.vectMap,
@@ -1859,7 +1928,7 @@
 ===================================================================
 --- gui/wxpython/scatt_plot/dialogs_iclass.py	(revision 0)
 +++ gui/wxpython/scatt_plot/dialogs_iclass.py	(working copy)
-@@ -0,0 +1,436 @@
+@@ -0,0 +1,464 @@
 +"""!
 + at package scatt_plot.dialogs
 +
@@ -1976,6 +2045,7 @@
 +
 +        self._doLayout()
 +        self.Bind(wx.EVT_SCROLLWIN, self.OnScroll)
++        self.Bind(aui.EVT_AUI_PANE_CLOSE, self.OnPlotPaneClosed)
 +
 +        dlgSize = (-1, 400)
 +        #self.SetBestSize(dlgSize)
@@ -1985,6 +2055,10 @@
 +        #if self.gwindow:         
 +        #    self.gwindow.SetSashPosition(int(self.GetSize()[1] * .75))
 +    
++    def OnPlotPaneClosed(self, event):
++        if isinstance(event.pane.window, ScatterPlotWidget):
++            event.pane.window.CleanUp()
++
 +    def OnScroll(self, event):
 +        event.Skip()
 +        wx.CallAfter(self._mgr.Update)
@@ -2024,6 +2098,8 @@
 +                           Center().Position(1).MaximizeButton(True).
 +                           MinimizeButton(True).CaptionVisible(True).
 +                           CloseButton(True).Layer(0))
++        
++
 +        self._mgr.Update()
 +  
 +        self.SetVirtualSize(self.GetBestVirtualSize())
@@ -2173,7 +2249,28 @@
 +
 +    def OnGetItemAttr(self, item):
 +        return None
++
++    def OnClassRightUp(self, event):
++        """!Show context menu on right click"""
++        item, flags = self.HitTest((event.GetX(), event.GetY()))
++        if item != wx.NOT_FOUND and flags & wx.LIST_HITTEST_ONITEM:
++            self.rightClickedItemIdx = item
++           
++        self.popupZoomtoAreas = wx.NewId()
++        self.Bind(wx.EVT_MENU, self.OnZoomToAreasByCat, id = self.popupZoomtoAreas)
++
++        # generate popup-menu
++        menu = wx.Menu()
++        menu.Append(self.popupZoomtoAreas, _("Zoom to training areas of selected class"))
 +        
++        self.PopupMenu(menu)
++        menu.Destroy()
++    
++    def OnZoomToAreasByCat(self, event):
++        """!Zoom to areas of given category"""
++        cat = self.stats_data.GetCategories()[self.rightClickedItemIdx]
++        self.mapWindow.ZoomToAreasByCat(cat)
++
 +class AddScattPlotDialog(wx.Dialog):
 +
 +    def __init__(self, parent, bands, id  = wx.ID_ANY):
@@ -2495,17 +2592,17 @@
 +                 'add_scatt_pl'  : MetaIcon(img = 'layer-raster-analyze',
 +                                            label = _('Add scatter plot')),
 +                 'editCatAdd'  : MetaIcon(img = 'polygon-create',
-+                                          label = _('Add region to category mode')),
++                                          label = _('Add region from scatter plot')),
 +                 'editCatRemove'  : MetaIcon(img = 'polygon-delete',
-+                                             label = _('Remove region to category mode')),
++                                             label = _('Remove region from scatter plot')),
 +                 'pan'        : MetaIcon(img = 'pan',
 +                                         label = _('Pan'),
-+                                         desc = _('Drag with mouse to pan scatter plots (zoom with holding right mouse button and draging')),
++                                         desc = _('Pan scatter plot')),
 +                'zoomIn'     : MetaIcon(img = 'zoom-in',
-+                                          label = _('Zoom in'),
-+                                          desc = _('Zoom with rectangle in scatter plots.')),
++                                          label = _('Zoom'),
++                                          desc = _('Zoom whith mouse wheel')),
 +                'cats_mgr' : MetaIcon(img = 'table-manager',
-+                                          label = _('Class manager'))
++                                          label = _('Show/hide class manager'))
 +                }
 +
 +        return self._getToolbarData((
@@ -2667,55 +2764,31 @@
 +
 +        return vars(self)[toolName]            
 \ No newline at end of file
-Index: gui/wxpython/mapdisp/toolbars.py
+Index: gui/wxpython/Makefile
 ===================================================================
---- gui/wxpython/mapdisp/toolbars.py	(revision 57453)
-+++ gui/wxpython/mapdisp/toolbars.py	(working copy)
-@@ -239,7 +239,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 57453)
-+++ gui/wxpython/mapdisp/frame.py	(working copy)
-@@ -225,6 +225,7 @@
-         #
-         self.dialogs = {}
-         self.dialogs['attributes'] = None
-+        self.dialogs['scatt_plot'] = None
-         self.dialogs['category'] = None
-         self.dialogs['barscale'] = None
-         self.dialogs['legend'] = None
-@@ -1168,6 +1169,19 @@
-         """!Returns toolbar with zooming tools"""
-         return self.toolbars['map']
+--- gui/wxpython/Makefile	(revision 57457)
++++ gui/wxpython/Makefile	(working copy)
+@@ -13,7 +13,7 @@
+ 	$(wildcard animation/* core/*.py dbmgr/* gcp/*.py gmodeler/* \
+ 	gui_core/*.py iclass/* lmgr/*.py location_wizard/*.py mapwin/*.py mapdisp/*.py \
+ 	mapswipe/* modules/*.py nviz/*.py psmap/* rlisetup/* vdigit/* \
+-	vnet/*.py web_services/*.py wxplot/*.py) \
++	vnet/*.py web_services/*.py wxplot/*.py scatt_plot/*.py) \
+ 	gis_set.py gis_set_error.py wxgui.py README
  
-+    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 
-         """
+ DSTFILES := $(patsubst %,$(ETCDIR)/%,$(SRCFILES)) \
+@@ -21,7 +21,7 @@
+ 
+ PYDSTDIRS := $(patsubst %,$(ETCDIR)/%,animation core dbmgr gcp gmodeler \
+ 	gui_core iclass lmgr location_wizard mapwin mapdisp modules nviz psmap \
+-	mapswipe vdigit wxplot web_services rlisetup vnet)
++	mapswipe vdigit wxplot web_services rlisetup vnet scatt_plot)
+ 
+ DSTDIRS := $(patsubst %,$(ETCDIR)/%,icons scripts xml)
+ 
 Index: gui/wxpython/vdigit/wxdigit.py
 ===================================================================
---- gui/wxpython/vdigit/wxdigit.py	(revision 57453)
+--- gui/wxpython/vdigit/wxdigit.py	(revision 57457)
 +++ gui/wxpython/vdigit/wxdigit.py	(working copy)
 @@ -17,7 +17,7 @@
  (and NumPy would be an excellent candidate for acceleration via
@@ -2735,14 +2808,16 @@
  from core.gcmd        import GError
  from core.debug       import Debug
  from core.settings    import UserSettings
-@@ -176,7 +178,19 @@
+@@ -176,7 +178,21 @@
          
          if self.poMapInfo:
              self.InitCats()
 -        
 +
-+        self.use_signals = False
++        self.emit_signals = False
 +
++        # signals which describes features changes during digitization, 
++        # activate them using EmitSignals method 
 +        #TODO signal for errors?
 +        self.featureAdded = Signal('IVDigit.featureAdded')
 +        self.areasDeleted = Signal('IVDigit.areasDeleted')
@@ -2756,7 +2831,21 @@
      def __del__(self):
          Debug.msg(1, "IVDigit.__del__()")
          Vect_destroy_line_struct(self.poPoints)
-@@ -394,7 +408,6 @@
+@@ -188,7 +204,12 @@
+             Vect_close(self.poBgMapInfo)
+             self.poBgMapInfo = self.popoBgMapInfo = None
+             del self.bgMapInfo
+-        
++     
++    def EmitSignals(self, emit):
++        """!Activate/deactivate signals which describes features changes during digitization.
++        """
++        self.emit_signals = emit
++
+     def CloseBackgroundMap(self):
+         """!Close background vector map"""
+         if not self.poBgMapInfo:
+@@ -394,7 +415,6 @@
          
          @return tuple (number of added features, feature ids)
          """
@@ -2764,7 +2853,7 @@
          layer = self._getNewFeaturesLayer()
          cat = self._getNewFeaturesCat()
          
-@@ -419,10 +432,14 @@
+@@ -419,10 +439,14 @@
              return (-1, None)
          
          self.toolbar.EnableUndo()
@@ -2775,7 +2864,7 @@
 +
 +        ret = self._addFeature(vtype, points, layer, cat,
 +                               self._getSnapMode(), self._display.GetThreshold())
-+        if ret[0] > -1:
++        if ret[0] > -1 and self.emit_signals:
 +            self.featureAdded.emit(new_bboxs = [self._createBbox(points)], new_areas_cats = [[{layer : [cat]}, None]])
 +
 +        return ret
@@ -2783,7 +2872,7 @@
      def DeleteSelectedLines(self):
          """!Delete selected features
  
-@@ -434,16 +451,27 @@
+@@ -434,16 +458,27 @@
          # collect categories for deleting if requested
          deleteRec = UserSettings.Get(group = 'vdigit', key = 'delRecord', subkey = 'enabled')
          catDict = dict()
@@ -2796,18 +2885,19 @@
                  if Vect_read_line(self.poMapInfo, None, self.poCats, i) < 0:
                      self._error.ReadLine(i)
                  
-+                ret = self._getLineAreaBboxCats(i)
-+                if ret:
-+                    old_bboxs += ret[0]
-+                    old_areas_cats += ret[1]
-+                
-                 cats = self.poCats.contents
+-                cats = self.poCats.contents
 -                for j in range(cats.n_cats):
 -                    if cats.field[j] not in catDict.keys():
 -                        catDict[cats.field[j]] = list()
 -                    catDict[cats.field[j]].append(cats.cat[j])
-+
++                if self.emit_signals:
++                    ret = self._getLineAreaBboxCats(i)
++                    if ret:
++                        old_bboxs += ret[0]
++                        old_areas_cats += ret[1]
++                
 +                # catDict was not used -> put into comment
++                #cats = self.poCats.contents
 +                #for j in range(cats.n_cats):
 +                #    if cats.field[j] not in catDict.keys():
 +                #        catDict[cats.field[j]] = list()
@@ -2815,17 +2905,19 @@
          
          poList = self._display.GetSelectedIList()
          nlines = Vedit_delete_lines(self.poMapInfo, poList)
-@@ -456,7 +484,8 @@
+@@ -456,7 +491,10 @@
                  self._deleteRecords(catDict)
              self._addChangeset()
              self.toolbar.EnableUndo()
 -        
-+            self.featuresDeleted.emit(old_bboxs = old_bboxs, old_areas_cats = old_areas_cats)
 +
++            if self.emit_signals:
++                self.featuresDeleted.emit(old_bboxs = old_bboxs, old_areas_cats = old_areas_cats)
++
          return nlines
              
      def _deleteRecords(self, cats):
-@@ -512,22 +541,171 @@
+@@ -512,22 +550,173 @@
  
          @return number of deleted 
          """
@@ -2845,18 +2937,20 @@
                  continue
 -            
 +
-+            area = Vect_get_centroid_area(self.poMapInfo, cList.value[i]);
-+            if area > 0: 
-+                bbox, cats = self._getaAreaBboxCats(area)
-+                old_bboxs += bbox
-+                old_areas_cats += cats
++            if self.emit_signals:
++                area = Vect_get_centroid_area(self.poMapInfo, cList.value[i]);
++                if area > 0: 
++                    bbox, cats = self._getaAreaBboxCats(area)
++                    old_bboxs += bbox
++                    old_areas_cats += cats
 +
              nareas += Vedit_delete_area_centroid(self.poMapInfo, cList.value[i])
          
          if nareas > 0:
              self._addChangeset()
              self.toolbar.EnableUndo()
-+            self.areasDeleted.emit(old_bboxs = old_bboxs, old_areas_cats = old_areas_cats)        
++            if self.emit_signals:
++                self.areasDeleted.emit(old_bboxs = old_bboxs, old_areas_cats = old_areas_cats)        
 +
 +        return nareas
 +   
@@ -2999,7 +3093,7 @@
      def MoveSelectedLines(self, move):
          """!Move selected features
  
-@@ -536,16 +714,43 @@
+@@ -536,16 +725,45 @@
          if not self._checkMap():
              return -1
          
@@ -3012,16 +3106,18 @@
          
          poList = self._display.GetSelectedIList()
 +
-+        old_bboxs = []
-+        old_areas_cats = []
-+        for sel_id in self._display.selected['ids']:
-+            ret = self._getLineAreaBboxCats(sel_id)
-+            if ret:
-+                old_bboxs += ret[0]
-+                old_areas_cats += ret[1]
++        if self.emit_signals:
++            old_bboxs = []
++            old_areas_cats = []
++            for sel_id in self._display.selected['ids']:
++                ret = self._getLineAreaBboxCats(sel_id)
++                if ret:
++                    old_bboxs += ret[0]
++                    old_areas_cats += ret[1]
 +        
-+        Vect_set_updated(self.poMapInfo, 1)
-+        n_up_lines_old = Vect_get_num_updated_lines(self.poMapInfo)
++            Vect_set_updated(self.poMapInfo, 1)
++            n_up_lines_old = Vect_get_num_updated_lines(self.poMapInfo)
++        
          nlines = Vedit_move_lines(self.poMapInfo, self.popoBgMapInfo, int(self.poBgMapInfo is not None),
                                    poList,
                                    move[0], move[1], 0,
@@ -3030,7 +3126,7 @@
          Vect_destroy_list(poList)
 -        
 +
-+        if nlines > 0:
++        if nlines > 0 and self.emit_signals:
 +            new_bboxs = []
 +            new_areas_cats = []
 +            n_up_lines = Vect_get_num_updated_lines(self.poMapInfo)
@@ -3044,21 +3140,22 @@
          if nlines > 0 and self._settings['breakLines']:
              for i in range(1, nlines):
                  self._breakLineAtIntersection(nlines + i, None, changeset)
-@@ -553,7 +758,12 @@
+@@ -553,7 +771,13 @@
          if nlines > 0:
              self._addChangeset()
              self.toolbar.EnableUndo()
 -        
 +            
-+            self.featuresMoved.emit(new_bboxs = new_bboxs,
-+                                    old_bboxs = old_bboxs, 
-+                                    old_areas_cats = old_areas_cats, 
-+                                    new_areas_cats = new_areas_cats)
++            if self.emit_signals:
++                self.featuresMoved.emit(new_bboxs = new_bboxs,
++                                        old_bboxs = old_bboxs, 
++                                        old_areas_cats = old_areas_cats, 
++                                        new_areas_cats = new_areas_cats)
 +
          return nlines
  
      def MoveSelectedVertex(self, point, move):
-@@ -571,12 +781,19 @@
+@@ -571,12 +795,21 @@
          
          if len(self._display.selected['ids']) != 1:
              return -1
@@ -3067,30 +3164,32 @@
 +        # move only first found vertex in bbox 
 +        poList = self._display.GetSelectedIList()
 +
-+        cList = poList.contents
-+        old_bboxs = [self._getBbox(cList.value[0])]
-+        old_areas_cats = [self._getLineAreasCategories(cList.value[0])]
++        if self.emit_signals:
++            cList = poList.contents
++            old_bboxs = [self._getBbox(cList.value[0])]
++            old_areas_cats = [self._getLineAreasCategories(cList.value[0])]
 +
++            Vect_set_updated(self.poMapInfo, 1)
++            n_up_lines_old = Vect_get_num_updated_lines(self.poMapInfo)
++
          Vect_reset_line(self.poPoints)
          Vect_append_point(self.poPoints, point[0], point[1], 0.0)
 -        
 -        # move only first found vertex in bbox 
 -        poList = self._display.GetSelectedIList()
 +
-+        Vect_set_updated(self.poMapInfo, 1)
-+        n_up_lines_old = Vect_get_num_updated_lines(self.poMapInfo)
          moved = Vedit_move_vertex(self.poMapInfo, self.popoBgMapInfo, int(self.poBgMapInfo is not None),
                                    poList, self.poPoints,
                                    self._display.GetThreshold(type = 'selectThresh'),
-@@ -584,7 +801,17 @@
+@@ -584,7 +817,17 @@
                                    move[0], move[1], 0.0,
                                    1, self._getSnapMode())
          Vect_destroy_list(poList)
 -        
 +
-+        n_up_lines = Vect_get_num_updated_lines(self.poMapInfo)
++        if moved > 0 and self.emit_signals:
++            n_up_lines = Vect_get_num_updated_lines(self.poMapInfo)
 +
-+        if moved > 0:
 +            new_bboxs = []
 +            new_areas_cats = []
 +            for i in range(n_up_lines_old, n_up_lines):
@@ -3101,80 +3200,82 @@
          if moved > 0 and self._settings['breakLines']:
              self._breakLineAtIntersection(Vect_get_num_lines(self.poMapInfo),
                                            None)
-@@ -592,7 +819,12 @@
+@@ -592,7 +835,13 @@
          if moved > 0:
              self._addChangeset()
              self.toolbar.EnableUndo()
 -        
 +
-+            self.vertexMoved.emit(new_bboxs = new_bboxs,  
-+                                  new_areas_cats = new_areas_cats, 
-+                                  old_areas_cats = old_areas_cats, 
-+                                  old_bboxs = old_bboxs)
++            if self.emit_signals:
++                self.vertexMoved.emit(new_bboxs = new_bboxs,  
++                                      new_areas_cats = new_areas_cats, 
++                                      old_areas_cats = old_areas_cats, 
++                                      old_bboxs = old_bboxs)
 +
          return moved
  
      def AddVertex(self, coords):
-@@ -681,6 +913,9 @@
+@@ -681,6 +930,10 @@
              self._error.ReadLine(line)
              return -1
          
-+        old_bboxs = [self._getBbox(line)]
-+        old_areas_cats = [self._getLineAreasCategories(line)]
++        if self.emit_signals:
++            old_bboxs = [self._getBbox(line)]
++            old_areas_cats = [self._getLineAreasCategories(line)]
 +
          # build feature geometry
          Vect_reset_line(self.poPoints)
          for p in coords:
-@@ -696,6 +931,9 @@
+@@ -696,6 +949,9 @@
          
          newline = Vect_rewrite_line(self.poMapInfo, line, ltype,
                                      self.poPoints, self.poCats)
-+        if newline > 0:
++        if newline > 0 and self.emit_signals:
 +            new_geom = [self._getBbox(newline)]
 +            new_areas_cats = [self._getLineAreasCategories(newline)]
          
          if newline > 0 and self._settings['breakLines']:
              self._breakLineAtIntersection(newline, None)
-@@ -703,7 +941,12 @@
+@@ -703,7 +959,13 @@
          if newline > 0:
              self._addChangeset()
              self.toolbar.EnableUndo()
 -        
 +    
-+            self.lineEdited.emit(old_bboxs = old_bboxs, 
-+                                 old_areas_cats = old_areas_cats, 
-+                                 new_bboxs = new_bboxs, 
-+                                 new_areas_cats = new_areas_cats)
++            if self.emit_signals:
++                self.lineEdited.emit(old_bboxs = old_bboxs, 
++                                     old_areas_cats = old_areas_cats, 
++                                     new_bboxs = new_bboxs, 
++                                     new_areas_cats = new_areas_cats)
 +
          return newline
  
      def FlipLine(self):
-@@ -1514,26 +1757,52 @@
+@@ -1514,6 +1776,16 @@
              return 0
          
          poList  = self._display.GetSelectedIList()
-+        cList = poList.contents
-+        
-+        old_bboxs = [self._getBbox(cList.value[0])]
-+        old_areas_cats = [self._getLineAreasCategories(cList.value[0])]
 +
++        if self.emit_signals:
++            cList = poList.contents
++            
++            old_bboxs = [self._getBbox(cList.value[0])]
++            old_areas_cats = [self._getLineAreasCategories(cList.value[0])]
++
++            Vect_set_updated(self.poMapInfo, 1)
++            n_up_lines_old = Vect_get_num_updated_lines(self.poMapInfo)
++
          Vect_reset_line(self.poPoints)
          Vect_append_point(self.poPoints, coords[0], coords[1], 0.0)
          
-         thresh = self._display.GetThreshold(type = 'selectThresh')
-         
-+        Vect_set_updated(self.poMapInfo, 1)
-+        n_up_lines_old = Vect_get_num_updated_lines(self.poMapInfo)
-         if add:
-             ret = Vedit_add_vertex(self.poMapInfo, poList,
-                                    self.poPoints, thresh)
+@@ -1525,15 +1797,35 @@
          else:
              ret = Vedit_remove_vertex(self.poMapInfo, poList,
                                        self.poPoints, thresh)
 +
          Vect_destroy_list(poList)
 +
-+        if ret > 0:
++        if ret > 0 and self.emit_signals:
 +            new_bboxs = []
 +            new_areas_cats = []
 +
@@ -3193,6 +3294,7 @@
              self._addChangeset()
 -                
 +
++        if ret > 0 and self.emit_signals:
 +            if add:
 +                self.vertexAdded.emit(old_bboxs = old_bboxs, new_bboxs = new_bboxs)
 +            else:
@@ -3206,7 +3308,7 @@
      def GetLineCats(self, line):
 Index: gui/wxpython/vdigit/toolbars.py
 ===================================================================
---- gui/wxpython/vdigit/toolbars.py	(revision 57453)
+--- gui/wxpython/vdigit/toolbars.py	(revision 57457)
 +++ gui/wxpython/vdigit/toolbars.py	(working copy)
 @@ -17,6 +17,7 @@
  import wx
@@ -3233,31 +3335,55 @@
          return True
  
      def StopEditing(self):
-Index: gui/wxpython/Makefile
+Index: gui/wxpython/mapdisp/toolbars.py
 ===================================================================
---- gui/wxpython/Makefile	(revision 57453)
-+++ gui/wxpython/Makefile	(working copy)
-@@ -13,7 +13,7 @@
- 	$(wildcard animation/* core/*.py dbmgr/* gcp/*.py gmodeler/* \
- 	gui_core/*.py iclass/* lmgr/*.py location_wizard/*.py mapwin/*.py mapdisp/*.py \
- 	mapswipe/* modules/*.py nviz/*.py psmap/* rlisetup/* vdigit/* \
--	vnet/*.py web_services/*.py wxplot/*.py) \
-+	vnet/*.py web_services/*.py wxplot/*.py scatt_plot/*.py) \
- 	gis_set.py gis_set_error.py wxgui.py README
+--- gui/wxpython/mapdisp/toolbars.py	(revision 57457)
++++ gui/wxpython/mapdisp/toolbars.py	(working copy)
+@@ -239,7 +239,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 57457)
++++ gui/wxpython/mapdisp/frame.py	(working copy)
+@@ -225,6 +225,7 @@
+         #
+         self.dialogs = {}
+         self.dialogs['attributes'] = None
++        self.dialogs['scatt_plot'] = None
+         self.dialogs['category'] = None
+         self.dialogs['barscale'] = None
+         self.dialogs['legend'] = None
+@@ -1168,6 +1169,19 @@
+         """!Returns toolbar with zooming tools"""
+         return self.toolbars['map']
  
- DSTFILES := $(patsubst %,$(ETCDIR)/%,$(SRCFILES)) \
-@@ -21,7 +21,7 @@
- 
- PYDSTDIRS := $(patsubst %,$(ETCDIR)/%,animation core dbmgr gcp gmodeler \
- 	gui_core iclass lmgr location_wizard mapwin mapdisp modules nviz psmap \
--	mapswipe vdigit wxplot web_services rlisetup vnet)
-+	mapswipe vdigit wxplot web_services rlisetup vnet scatt_plot)
- 
- DSTDIRS := $(patsubst %,$(ETCDIR)/%,icons scripts xml)
- 
++    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: gui/wxpython/iclass/dialogs.py
 ===================================================================
---- gui/wxpython/iclass/dialogs.py	(revision 57453)
+--- gui/wxpython/iclass/dialogs.py	(revision 57457)
 +++ gui/wxpython/iclass/dialogs.py	(working copy)
 @@ -333,13 +333,19 @@
          toolbar.SetCategories(catNames = catNames, catIdx = cats)
@@ -3282,7 +3408,7 @@
      def GetSelectedIndices(self, state =  wx.LIST_STATE_SELECTED):
 Index: gui/wxpython/iclass/toolbars.py
 ===================================================================
---- gui/wxpython/iclass/toolbars.py	(revision 57453)
+--- gui/wxpython/iclass/toolbars.py	(revision 57457)
 +++ gui/wxpython/iclass/toolbars.py	(working copy)
 @@ -46,9 +46,7 @@
          'importAreas' : MetaIcon(img = 'layer-import',
@@ -3318,7 +3444,7 @@
                                        self.parent.OnCategoryManager),
 Index: gui/wxpython/iclass/frame.py
 ===================================================================
---- gui/wxpython/iclass/frame.py	(revision 57453)
+--- gui/wxpython/iclass/frame.py	(revision 57457)
 +++ gui/wxpython/iclass/frame.py	(working copy)
 @@ -64,6 +64,8 @@
                                 IClassExportAreasDialog, IClassMapDialog
@@ -3438,7 +3564,7 @@
      
 Index: gui/wxpython/iclass/plots.py
 ===================================================================
---- gui/wxpython/iclass/plots.py	(revision 57453)
+--- gui/wxpython/iclass/plots.py	(revision 57457)
 +++ gui/wxpython/iclass/plots.py	(working copy)
 @@ -28,7 +28,7 @@
      for each band and for one category. Coincidence plots show min max range
@@ -3567,421 +3693,26 @@
      def DrawCoincidencePlots(self):
          """!Draw coincidence plots"""
          for bandIdx in range(len(self.bandList)):
-Index: lib/imagery/scatt_sccats.c
+Index: lib/vector/Vlib/open.c
 ===================================================================
---- lib/imagery/scatt_sccats.c	(revision 0)
-+++ lib/imagery/scatt_sccats.c	(working copy)
-@@ -0,0 +1,405 @@
-+/*!
-+   \file lib/imagery/scatt_cat_rast.c
-+
-+   \brief Imagery library - functions for manipulation with scatter plot structs.
-+
-+   Copyright (C) 2013 by the GRASS Development Team
-+
-+   This program is free software under the GNU General Public License
-+   (>=v2).  Read the file COPYING that comes with GRASS for details.
-+
-+   \author Stepan Turek <stepan.turek at seznam.cz> (Mentor: Martin Landa)
-+ */
-+
-+#include <grass/raster.h>
-+#include <grass/imagery.h>
-+#include <grass/gis.h>
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <math.h>
-+#include <string.h>
-+
-+/*!
-+   \brief Compute band ids from scatter plot id.
-+
-+    Scatter plot id describes which bands defines the scatter plot.
-+
-+    Let say we have 3 bands, their ids are 0, 1 and 2.
-+    Scatter plot with id 0 consists of band 1 (b_1_id) 0 and  band 2 (b_2_id) 1.
-+    All scatter plots:
-+    scatt_id b_1_id b_2_id
-+    0        0      1
-+    1        0      2
-+    2        1      2
-+
-+   \param scatt_id scatter plot id
-+   \param n_bands number of bands
-+   \param [out] b_1_id id of band1
-+   \param[out] b_2_id id of band2
-+
-+   \return 0
-+ */
-+int I_id_scatt_to_bands(const int scatt_id, const int n_bands, int * b_1_id, int * b_2_id)
-+{   
-+    int n_b1 = n_bands - 1;
-+
-+    * b_1_id = (int) ((2 * n_b1 + 1 - sqrt((double)((2 * n_b1 + 1) * (2 * n_b1 + 1) - 8 * scatt_id))) / 2);
-+
-+    * b_2_id = scatt_id - ((* b_1_id) * (2 * n_b1 + 1) - (* b_1_id) * (* b_1_id)) / 2 + (* b_1_id) + 1;
-+
-+    return 0;
-+}
-+
-+
-+/*!
-+   \brief Compute scatter plot id from band ids.
-+
-+    See also I_id_scatt_to_bands().
-+
-+   \param n_bands number of bands
-+   \param b_1_id id of band1
-+   \param b_1_id id of band2
-+   \param [out] scatt_id scatter plot id
-+
-+   \return 0
-+ */
-+int I_bands_to_id_scatt(const int b_1_id, const int b_2_id, const int n_bands, int * scatt_id)
-+{   
-+    int n_b1 = n_bands - 1;
-+
-+    * scatt_id = (b_1_id * (2 * n_b1 + 1) - b_1_id * b_1_id) / 2 + b_2_id - b_1_id - 1;
-+
-+    return 0;
-+}
-+
-+/*!
-+   \brief Initialize structure for storing scatter plots data.
-+
-+   \param cats pointer to scCats struct 
-+   \param n_bands number of bands
-+   \param type SC_SCATT_DATA - stores scatter plots 
-+   \param type SC_SCATT_CONDITIONS - stores selected areas in scatter plots
-+ */
-+void I_sc_init_cats(struct scCats * cats, int n_bands, int type)
-+{
-+    int i_cat;
-+
-+    cats->type = type;
-+
-+    cats->n_cats = 100;
-+    cats->n_a_cats = 0;
-+
-+    cats->n_bands = n_bands;
-+    cats->n_scatts = (n_bands - 1) * n_bands / 2;
-+
-+    cats->cats_arr = (struct scScatts **) G_malloc(cats->n_cats * sizeof(struct scScatts *));
-+    memset(cats->cats_arr, 0, cats-> n_cats * sizeof(struct scScatts *));
-+
-+    cats->cats_ids = (int *)  G_malloc(cats->n_cats * sizeof(int));
-+    cats->cats_idxs =(int *)  G_malloc(cats->n_cats * sizeof(int));
-+
-+    for(i_cat = 0; i_cat < cats->n_cats; i_cat++)
-+        cats->cats_idxs[i_cat] = -1;
-+
-+    return;
-+}
-+
-+/*!
-+   \brief Free data of struct scCats, the structure itself remains alocated.
-+
-+   \param cats pointer to existing scCats struct
-+ */
-+void I_sc_free_cats(struct scCats * cats)
-+{
-+    int i_cat;
-+
-+    for(i_cat = 0; i_cat < cats->n_a_cats; i_cat++)
-+    {        
-+        if(cats->cats_arr[i_cat])
-+        {   
-+            G_free(cats->cats_arr[i_cat]->scatt_idxs);
-+            G_free(cats->cats_arr[i_cat]->scatts_bands);
-+            G_free(cats->cats_arr[i_cat]->scatts_arr);
-+            G_free(cats->cats_arr[i_cat]);
-+        }
-+    }
-+
-+    G_free(cats->cats_ids);
-+    G_free(cats->cats_idxs);
-+    G_free(cats->cats_arr);
-+
-+    cats->n_cats = 0;
-+    cats->n_a_cats = 0;
-+    cats->n_bands = 0;
-+    cats->n_scatts = 0;
-+    cats->type = -1;
-+
-+    return;
-+}
-+
-+#if 0
-+void I_sc_get_active_categories(int * a_cats_ids, int * n_a_cats, struct scCats * cats)
-+{
-+    a_cats_ids = cats->cats_ids;
-+    * n_a_cats = cats->n_a_cats;
-+}
-+#endif
-+
-+/*!
-+   \brief Add category.
-+    
-+    Category represents group of scatter plots.
-+
-+   \param cats pointer to scCats struct
-+
-+   \return assigned category id (starts with 0)
-+   \return -1 if maximum nuber of categories was reached
-+ */
-+int I_sc_add_cat(struct scCats * cats)
-+{
-+    int i_scatt, i_cat_id, cat_id;
-+    int n_a_cats = cats->n_a_cats;
-+
-+    if(cats->n_a_cats >= cats->n_cats)
-+        return -1;
-+
-+    for(i_cat_id = 0; i_cat_id < cats->n_cats; i_cat_id++)
-+        if(cats->cats_idxs[i_cat_id] < 0) {
-+            cat_id = i_cat_id;
-+            break;
-+        }
-+
-+    cats->cats_ids[n_a_cats] = cat_id;
-+    cats->cats_idxs[cat_id] = n_a_cats;
-+    
-+    cats->cats_arr[n_a_cats] = (struct scScatts *) G_malloc(sizeof(struct scScatts));
-+
-+    cats->cats_arr[n_a_cats]->scatts_arr = (struct scdScattData **) G_malloc(cats->n_scatts * sizeof(struct scdScattData *));
-+    memset((cats->cats_arr[n_a_cats]->scatts_arr), 0, cats->n_scatts * sizeof(struct scdScattData *));
-+    
-+    cats->cats_arr[n_a_cats]->n_a_scatts = 0;
-+
-+    cats->cats_arr[n_a_cats]->scatts_bands = (int *) G_malloc(cats->n_scatts * 2 * sizeof(int));
-+     
-+    cats->cats_arr[n_a_cats]->scatt_idxs = (int *) G_malloc(cats->n_scatts * sizeof(int));
-+    for(i_scatt = 0; i_scatt < cats->n_scatts; i_scatt++)
-+        cats->cats_arr[n_a_cats]->scatt_idxs[i_scatt] = -1;
-+    
-+    ++cats->n_a_cats;
-+
-+    return cat_id;
-+}
-+
-+#if 0
-+int I_sc_delete_cat(struct scCats * cats, int cat_id)
-+{
-+    int cat_idx, i_cat;
-+
-+    if(cat_id < 0 || cat_id >= cats->n_cats)
-+        return -1;
-+
-+    cat_idx = cats->cats_idxs[cat_id];
-+    if(cat_idx < 0)
-+        return -1;
-+
-+    G_free(cats->cats_arr[cat_idx]->scatt_idxs);
-+    G_free(cats->cats_arr[cat_idx]->scatts_bands);
-+    G_free(cats->cats_arr[cat_idx]->scatts_arr);
-+    G_free(cats->cats_arr[cat_idx]);
-+
-+    for(i_cat = cat_idx; i_cat < cats->n_a_cats - 1; i_cat++)
-+    {
-+        cats->cats_arr[i_cat] = cats->cats_arr[i_cat + 1];
-+        cats->cats_ids[i_cat] = cats->cats_ids[i_cat + 1];
-+    }
-+    cats->cats_idxs[cat_id] = -1; 
-+
-+    --cats->n_a_cats;
-+    
-+    return 0;
-+}
-+#endif
-+
-+/*!
-+   \brief Insert scatter plot data .
-+    Inserted scatt_data struct must have same type as cats struct (SC_SCATT_DATA or SC_SCATT_CONDITIONS).
-+
-+   \param cats pointer to scCats struct
-+   \param cat_id id number of category.
-+   \param scatt_id id number of scatter plot.
-+
-+   \return  0 on success
-+   \return -1 on failure
-+ */
-+int I_sc_insert_scatt_data(struct scCats * cats, struct scdScattData * scatt_data, int cat_id, int scatt_id)
-+{
-+    int band_1, band_2, cat_idx, n_a_scatts;
-+    struct scScatts * scatts;
-+
-+    if(cat_id < 0 || cat_id >= cats->n_cats)
-+        return -1;
-+
-+    cat_idx = cats->cats_idxs[cat_id];
-+    if(cat_idx < 0)
-+        return -1;
-+
-+    if(scatt_id < 0 && scatt_id >= cats->n_scatts)
-+        return -1;
-+
-+    scatts = cats->cats_arr[cat_idx];
-+    if(scatts->scatt_idxs[scatt_id] >= 0)
-+        return -1;
-+
-+    if(!scatt_data->b_conds_arr && cats->type == SC_SCATT_CONDITIONS)
-+        return -1;
-+
-+    if(!scatt_data->scatt_vals_arr && cats->type == SC_SCATT_DATA)
-+        return -1;
-+
-+    n_a_scatts = scatts->n_a_scatts;
-+
-+    scatts->scatt_idxs[scatt_id] = n_a_scatts;
-+
-+    I_id_scatt_to_bands(scatt_id, cats->n_bands, &band_1, &band_2);
-+
-+    scatts->scatts_bands[n_a_scatts * 2] = band_1;
-+    scatts->scatts_bands[n_a_scatts * 2 + 1] = band_2;
-+
-+    scatts->scatts_arr[n_a_scatts] = scatt_data;
-+    ++scatts->n_a_scatts;
-+
-+    return 0;
-+}
-+
-+#if 0
-+int I_sc_remove_scatt_data(struct scCats * cats, struct scdScattData * scatt_data, int cat_id, int scatt_id)
-+{
-+    int cat_idx, scatt_idx, n_init_scatts, i_scatt;
-+    struct scScatts * scatts;
-+
-+    if(cat_id < 0 && cat_id >= cats->n_cats)
-+        return -1;
-+
-+    cat_idx = cats->cats_idxs[cat_id];
-+    if(cat_idx < 0)
-+        return -1;
-+
-+    if(scatt_id < 0 || scatt_id >= cats->n_scatts)
-+        return -1;
-+
-+    scatts = cats->cats_arr[cat_idx];
-+    if(scatts->scatt_idxs[scatt_id] < 0)
-+        return -1;
-+
-+    scatt_data = scatts->scatts_arr[scatt_idx];
-+
-+    for(i_scatt = scatt_idx; i_scatt < scatts->n_a_scatts - 1; i_scatt++)
-+    {
-+        scatts->scatts_arr[i_scatt] = scatts->scatts_arr[i_scatt + 1];
-+        scatts->scatts_bands[i_scatt * 2] = scatts->scatts_bands[(i_scatt + 1)* 2];
-+        scatts->scatts_bands[i_scatt * 2 + 1] = scatts->scatts_bands[(i_scatt + 1) * 2 + 1];
-+    }
-+    scatts->scatts_arr[scatts->n_a_scatts] = NULL;
-+
-+    scatts->scatt_idxs[scatt_id] = -1;
-+
-+    scatt_data = scatts->scatts_arr[scatt_id];
-+    scatts->n_a_scatts--;
-+
-+    return 0;
-+}
-+
-+int I_sc_set_value(struct scCats * cats, int cat_id, int scatt_id, int value_idx, int value)
-+{
-+    int n_a_scatts = cats->cats_arr[cat_id]->n_a_scatts;
-+    int cat_idx, scatt_idx, ret;
-+
-+    cat_idx = cats->cats_idxs[cat_id];
-+    if(cat_idx < 0)
-+        return -1;
-+    
-+    if(cats->cats_arr[cat_idx]->scatt_idxs[scatt_id] < 0)
-+        return -1;
-+
-+    cat_idx = cats->cats_idxs[cat_id];
-+    scatt_idx = cats->cats_arr[cat_idx]->scatt_idxs[scatt_id];
-+
-+    I_scd_set_value(cats->cats_arr[cat_idx]->scatts_arr[scatt_idx], value_idx, value);
-+
-+    return 0;
-+}
-+#endif
-+
-+/*!
-+   \brief Insert scatter plot data.
-+    
-+   \param scatt_data pointer to existing struct scdScattData
-+   \param type SC_SCATT_DATA for scatter plots or SC_SCATT_CONDITIONS for selected areas in scatter plot
-+   \param n_vals number of data values
-+   \param data array of values (unsigned char for SC_SCATT_CONDITIONS, unsigned int for SC_SCATT_DATA)
-+ */
-+void I_scd_init_scatt_data(struct scdScattData * scatt_data, int type, int n_vals, void * data)
-+{
-+    scatt_data->n_vals = n_vals;
-+
-+    if(type == SC_SCATT_DATA)
-+    {   
-+        if(data)
-+            scatt_data->scatt_vals_arr = (unsigned int *) data;
-+        else {
-+            scatt_data->scatt_vals_arr = (unsigned int *) G_malloc(n_vals * sizeof(unsigned int));
-+            memset(scatt_data->scatt_vals_arr, 0, n_vals * sizeof(unsigned int)); 
-+        }
-+        scatt_data->b_conds_arr = NULL;
-+    }
-+    else if(type == SC_SCATT_CONDITIONS)
-+    {
-+        if(data)
-+            scatt_data->b_conds_arr = (unsigned char *) data;
-+        else {
-+            scatt_data->b_conds_arr = (unsigned char *) G_malloc(n_vals * sizeof(unsigned char));
-+            memset(scatt_data->b_conds_arr, 0, n_vals * sizeof(unsigned char));
-+        }
-+        scatt_data->scatt_vals_arr = NULL;
-+    }
-+
-+    return;
-+}
-+
-+
-+#if 0
-+void I_scd_get_range_min_max(struct scdScattData * scatt_data, CELL * band_1_min, CELL * band_1_max, CELL * band_2_min, CELL * band_2_max)
-+{
-+
-+    Rast_get_range_min_max(&(scatt_data->band_1_range), band_1_min, band_2_min);
-+    Rast_get_range_min_max(&(scatt_data->band_2_range), band_2_min, band_2_max);
-+
-+    return;
-+}
-+s
-+void * I_scd_get_data_ptr(struct scdScattData * scatt_data)
-+{
-+    if(!scatt_data->b_conds_arr)
-+        return scatt_data->b_conds_arr;
-+    else if(!scatt_data->scatt_vals_arr)
-+        return scatt_data->scatt_vals_arr;
-+
-+    return NULL;
-+}
-+
-+int I_scd_set_value(struct scdScattData * scatt_data, unsigned int val_idx, unsigned int val)
-+{
-+    if(val_idx < 0 && val_idx >  scatt_data->n_vals)
-+        return -1;
-+
-+    if(scatt_data->b_conds_arr)
-+        scatt_data->b_conds_arr[val_idx] = val;
-+    else if(scatt_data->scatt_vals_arr)
-+        scatt_data->scatt_vals_arr[val_idx] = val;
-+    else
-+        return -1;
-+
-+    return 0;
-+}
-+#endif
+--- lib/vector/Vlib/open.c	(revision 57457)
++++ lib/vector/Vlib/open.c	(working copy)
+@@ -240,7 +240,9 @@
+         }
+         else {
+             char file_path[GPATH_MAX];
+-            
++            /* reduce to current mapset if search path was set */
++            if(strcmp(Map->mapset, "") == 0)
++                Map->mapset = G_store(G_mapset());
+             if (strcmp(Map->mapset, G_mapset()) != 0) {
+                 G_warning(_("Temporary vector maps can be accessed only in the current mapset"));
+                 return -1;
 Index: lib/imagery/scatt.c
 ===================================================================
 --- lib/imagery/scatt.c	(revision 0)
 +++ lib/imagery/scatt.c	(working copy)
-@@ -0,0 +1,745 @@
+@@ -0,0 +1,746 @@
 +/*!
 +   \file lib/imagery/scatt.c
 +
@@ -4437,6 +4168,7 @@
 +            /* check conditions from category raster condtitions file */
 +            if(f_cats_rasts_conds[i_cat]) {
 +                n_pixs = fread(rast_pixs, sizeof(unsigned char), (row_size)/sizeof(unsigned char), f_cats_rasts_conds[i_cat]);
++
 +                if (ferror(f_cats_rasts_conds[i_cat]))
 +                {
 +                    G_free(rast_pixs);
@@ -4728,3 +4460,413 @@
 +    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,405 @@
++/*!
++   \file lib/imagery/scatt_cat_rast.c
++
++   \brief Imagery library - functions for manipulation with scatter plot structs.
++
++   Copyright (C) 2013 by the GRASS Development Team
++
++   This program is free software under the GNU General Public License
++   (>=v2).  Read the file COPYING that comes with GRASS for details.
++
++   \author Stepan Turek <stepan.turek at seznam.cz> (Mentor: Martin Landa)
++ */
++
++#include <grass/raster.h>
++#include <grass/imagery.h>
++#include <grass/gis.h>
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <math.h>
++#include <string.h>
++
++/*!
++   \brief Compute band ids from scatter plot id.
++
++    Scatter plot id describes which bands defines the scatter plot.
++
++    Let say we have 3 bands, their ids are 0, 1 and 2.
++    Scatter plot with id 0 consists of band 1 (b_1_id) 0 and  band 2 (b_2_id) 1.
++    All scatter plots:
++    scatt_id b_1_id b_2_id
++    0        0      1
++    1        0      2
++    2        1      2
++
++   \param scatt_id scatter plot id
++   \param n_bands number of bands
++   \param [out] b_1_id id of band1
++   \param[out] b_2_id id of band2
++
++   \return 0
++ */
++int I_id_scatt_to_bands(const int scatt_id, const int n_bands, int * b_1_id, int * b_2_id)
++{   
++    int n_b1 = n_bands - 1;
++
++    * b_1_id = (int) ((2 * n_b1 + 1 - sqrt((double)((2 * n_b1 + 1) * (2 * n_b1 + 1) - 8 * scatt_id))) / 2);
++
++    * b_2_id = scatt_id - ((* b_1_id) * (2 * n_b1 + 1) - (* b_1_id) * (* b_1_id)) / 2 + (* b_1_id) + 1;
++
++    return 0;
++}
++
++
++/*!
++   \brief Compute scatter plot id from band ids.
++
++    See also I_id_scatt_to_bands().
++
++   \param n_bands number of bands
++   \param b_1_id id of band1
++   \param b_1_id id of band2
++   \param [out] scatt_id scatter plot id
++
++   \return 0
++ */
++int I_bands_to_id_scatt(const int b_1_id, const int b_2_id, const int n_bands, int * scatt_id)
++{   
++    int n_b1 = n_bands - 1;
++
++    * scatt_id = (b_1_id * (2 * n_b1 + 1) - b_1_id * b_1_id) / 2 + b_2_id - b_1_id - 1;
++
++    return 0;
++}
++
++/*!
++   \brief Initialize structure for storing scatter plots data.
++
++   \param cats pointer to scCats struct 
++   \param n_bands number of bands
++   \param type SC_SCATT_DATA - stores scatter plots 
++   \param type SC_SCATT_CONDITIONS - stores selected areas in scatter plots
++ */
++void I_sc_init_cats(struct scCats * cats, int n_bands, int type)
++{
++    int i_cat;
++
++    cats->type = type;
++
++    cats->n_cats = 100;
++    cats->n_a_cats = 0;
++
++    cats->n_bands = n_bands;
++    cats->n_scatts = (n_bands - 1) * n_bands / 2;
++
++    cats->cats_arr = (struct scScatts **) G_malloc(cats->n_cats * sizeof(struct scScatts *));
++    memset(cats->cats_arr, 0, cats-> n_cats * sizeof(struct scScatts *));
++
++    cats->cats_ids = (int *)  G_malloc(cats->n_cats * sizeof(int));
++    cats->cats_idxs =(int *)  G_malloc(cats->n_cats * sizeof(int));
++
++    for(i_cat = 0; i_cat < cats->n_cats; i_cat++)
++        cats->cats_idxs[i_cat] = -1;
++
++    return;
++}
++
++/*!
++   \brief Free data of struct scCats, the structure itself remains alocated.
++
++   \param cats pointer to existing scCats struct
++ */
++void I_sc_free_cats(struct scCats * cats)
++{
++    int i_cat;
++
++    for(i_cat = 0; i_cat < cats->n_a_cats; i_cat++)
++    {        
++        if(cats->cats_arr[i_cat])
++        {   
++            G_free(cats->cats_arr[i_cat]->scatt_idxs);
++            G_free(cats->cats_arr[i_cat]->scatts_bands);
++            G_free(cats->cats_arr[i_cat]->scatts_arr);
++            G_free(cats->cats_arr[i_cat]);
++        }
++    }
++
++    G_free(cats->cats_ids);
++    G_free(cats->cats_idxs);
++    G_free(cats->cats_arr);
++
++    cats->n_cats = 0;
++    cats->n_a_cats = 0;
++    cats->n_bands = 0;
++    cats->n_scatts = 0;
++    cats->type = -1;
++
++    return;
++}
++
++#if 0
++void I_sc_get_active_categories(int * a_cats_ids, int * n_a_cats, struct scCats * cats)
++{
++    a_cats_ids = cats->cats_ids;
++    * n_a_cats = cats->n_a_cats;
++}
++#endif
++
++/*!
++   \brief Add category.
++    
++    Category represents group of scatter plots.
++
++   \param cats pointer to scCats struct
++
++   \return assigned category id (starts with 0)
++   \return -1 if maximum nuber of categories was reached
++ */
++int I_sc_add_cat(struct scCats * cats)
++{
++    int i_scatt, i_cat_id, cat_id;
++    int n_a_cats = cats->n_a_cats;
++
++    if(cats->n_a_cats >= cats->n_cats)
++        return -1;
++
++    for(i_cat_id = 0; i_cat_id < cats->n_cats; i_cat_id++)
++        if(cats->cats_idxs[i_cat_id] < 0) {
++            cat_id = i_cat_id;
++            break;
++        }
++
++    cats->cats_ids[n_a_cats] = cat_id;
++    cats->cats_idxs[cat_id] = n_a_cats;
++    
++    cats->cats_arr[n_a_cats] = (struct scScatts *) G_malloc(sizeof(struct scScatts));
++
++    cats->cats_arr[n_a_cats]->scatts_arr = (struct scdScattData **) G_malloc(cats->n_scatts * sizeof(struct scdScattData *));
++    memset((cats->cats_arr[n_a_cats]->scatts_arr), 0, cats->n_scatts * sizeof(struct scdScattData *));
++    
++    cats->cats_arr[n_a_cats]->n_a_scatts = 0;
++
++    cats->cats_arr[n_a_cats]->scatts_bands = (int *) G_malloc(cats->n_scatts * 2 * sizeof(int));
++     
++    cats->cats_arr[n_a_cats]->scatt_idxs = (int *) G_malloc(cats->n_scatts * sizeof(int));
++    for(i_scatt = 0; i_scatt < cats->n_scatts; i_scatt++)
++        cats->cats_arr[n_a_cats]->scatt_idxs[i_scatt] = -1;
++    
++    ++cats->n_a_cats;
++
++    return cat_id;
++}
++
++#if 0
++int I_sc_delete_cat(struct scCats * cats, int cat_id)
++{
++    int cat_idx, i_cat;
++
++    if(cat_id < 0 || cat_id >= cats->n_cats)
++        return -1;
++
++    cat_idx = cats->cats_idxs[cat_id];
++    if(cat_idx < 0)
++        return -1;
++
++    G_free(cats->cats_arr[cat_idx]->scatt_idxs);
++    G_free(cats->cats_arr[cat_idx]->scatts_bands);
++    G_free(cats->cats_arr[cat_idx]->scatts_arr);
++    G_free(cats->cats_arr[cat_idx]);
++
++    for(i_cat = cat_idx; i_cat < cats->n_a_cats - 1; i_cat++)
++    {
++        cats->cats_arr[i_cat] = cats->cats_arr[i_cat + 1];
++        cats->cats_ids[i_cat] = cats->cats_ids[i_cat + 1];
++    }
++    cats->cats_idxs[cat_id] = -1; 
++
++    --cats->n_a_cats;
++    
++    return 0;
++}
++#endif
++
++/*!
++   \brief Insert scatter plot data .
++    Inserted scatt_data struct must have same type as cats struct (SC_SCATT_DATA or SC_SCATT_CONDITIONS).
++
++   \param cats pointer to scCats struct
++   \param cat_id id number of category.
++   \param scatt_id id number of scatter plot.
++
++   \return  0 on success
++   \return -1 on failure
++ */
++int I_sc_insert_scatt_data(struct scCats * cats, struct scdScattData * scatt_data, int cat_id, int scatt_id)
++{
++    int band_1, band_2, cat_idx, n_a_scatts;
++    struct scScatts * scatts;
++
++    if(cat_id < 0 || cat_id >= cats->n_cats)
++        return -1;
++
++    cat_idx = cats->cats_idxs[cat_id];
++    if(cat_idx < 0)
++        return -1;
++
++    if(scatt_id < 0 && scatt_id >= cats->n_scatts)
++        return -1;
++
++    scatts = cats->cats_arr[cat_idx];
++    if(scatts->scatt_idxs[scatt_id] >= 0)
++        return -1;
++
++    if(!scatt_data->b_conds_arr && cats->type == SC_SCATT_CONDITIONS)
++        return -1;
++
++    if(!scatt_data->scatt_vals_arr && cats->type == SC_SCATT_DATA)
++        return -1;
++
++    n_a_scatts = scatts->n_a_scatts;
++
++    scatts->scatt_idxs[scatt_id] = n_a_scatts;
++
++    I_id_scatt_to_bands(scatt_id, cats->n_bands, &band_1, &band_2);
++
++    scatts->scatts_bands[n_a_scatts * 2] = band_1;
++    scatts->scatts_bands[n_a_scatts * 2 + 1] = band_2;
++
++    scatts->scatts_arr[n_a_scatts] = scatt_data;
++    ++scatts->n_a_scatts;
++
++    return 0;
++}
++
++#if 0
++int I_sc_remove_scatt_data(struct scCats * cats, struct scdScattData * scatt_data, int cat_id, int scatt_id)
++{
++    int cat_idx, scatt_idx, n_init_scatts, i_scatt;
++    struct scScatts * scatts;
++
++    if(cat_id < 0 && cat_id >= cats->n_cats)
++        return -1;
++
++    cat_idx = cats->cats_idxs[cat_id];
++    if(cat_idx < 0)
++        return -1;
++
++    if(scatt_id < 0 || scatt_id >= cats->n_scatts)
++        return -1;
++
++    scatts = cats->cats_arr[cat_idx];
++    if(scatts->scatt_idxs[scatt_id] < 0)
++        return -1;
++
++    scatt_data = scatts->scatts_arr[scatt_idx];
++
++    for(i_scatt = scatt_idx; i_scatt < scatts->n_a_scatts - 1; i_scatt++)
++    {
++        scatts->scatts_arr[i_scatt] = scatts->scatts_arr[i_scatt + 1];
++        scatts->scatts_bands[i_scatt * 2] = scatts->scatts_bands[(i_scatt + 1)* 2];
++        scatts->scatts_bands[i_scatt * 2 + 1] = scatts->scatts_bands[(i_scatt + 1) * 2 + 1];
++    }
++    scatts->scatts_arr[scatts->n_a_scatts] = NULL;
++
++    scatts->scatt_idxs[scatt_id] = -1;
++
++    scatt_data = scatts->scatts_arr[scatt_id];
++    scatts->n_a_scatts--;
++
++    return 0;
++}
++
++int I_sc_set_value(struct scCats * cats, int cat_id, int scatt_id, int value_idx, int value)
++{
++    int n_a_scatts = cats->cats_arr[cat_id]->n_a_scatts;
++    int cat_idx, scatt_idx, ret;
++
++    cat_idx = cats->cats_idxs[cat_id];
++    if(cat_idx < 0)
++        return -1;
++    
++    if(cats->cats_arr[cat_idx]->scatt_idxs[scatt_id] < 0)
++        return -1;
++
++    cat_idx = cats->cats_idxs[cat_id];
++    scatt_idx = cats->cats_arr[cat_idx]->scatt_idxs[scatt_id];
++
++    I_scd_set_value(cats->cats_arr[cat_idx]->scatts_arr[scatt_idx], value_idx, value);
++
++    return 0;
++}
++#endif
++
++/*!
++   \brief Insert scatter plot data.
++    
++   \param scatt_data pointer to existing struct scdScattData
++   \param type SC_SCATT_DATA for scatter plots or SC_SCATT_CONDITIONS for selected areas in scatter plot
++   \param n_vals number of data values
++   \param data array of values (unsigned char for SC_SCATT_CONDITIONS, unsigned int for SC_SCATT_DATA)
++ */
++void I_scd_init_scatt_data(struct scdScattData * scatt_data, int type, int n_vals, void * data)
++{
++    scatt_data->n_vals = n_vals;
++
++    if(type == SC_SCATT_DATA)
++    {   
++        if(data)
++            scatt_data->scatt_vals_arr = (unsigned int *) data;
++        else {
++            scatt_data->scatt_vals_arr = (unsigned int *) G_malloc(n_vals * sizeof(unsigned int));
++            memset(scatt_data->scatt_vals_arr, 0, n_vals * sizeof(unsigned int)); 
++        }
++        scatt_data->b_conds_arr = NULL;
++    }
++    else if(type == SC_SCATT_CONDITIONS)
++    {
++        if(data)
++            scatt_data->b_conds_arr = (unsigned char *) data;
++        else {
++            scatt_data->b_conds_arr = (unsigned char *) G_malloc(n_vals * sizeof(unsigned char));
++            memset(scatt_data->b_conds_arr, 0, n_vals * sizeof(unsigned char));
++        }
++        scatt_data->scatt_vals_arr = NULL;
++    }
++
++    return;
++}
++
++
++#if 0
++void I_scd_get_range_min_max(struct scdScattData * scatt_data, CELL * band_1_min, CELL * band_1_max, CELL * band_2_min, CELL * band_2_max)
++{
++
++    Rast_get_range_min_max(&(scatt_data->band_1_range), band_1_min, band_2_min);
++    Rast_get_range_min_max(&(scatt_data->band_2_range), band_2_min, band_2_max);
++
++    return;
++}
++s
++void * I_scd_get_data_ptr(struct scdScattData * scatt_data)
++{
++    if(!scatt_data->b_conds_arr)
++        return scatt_data->b_conds_arr;
++    else if(!scatt_data->scatt_vals_arr)
++        return scatt_data->scatt_vals_arr;
++
++    return NULL;
++}
++
++int I_scd_set_value(struct scdScattData * scatt_data, unsigned int val_idx, unsigned int val)
++{
++    if(val_idx < 0 && val_idx >  scatt_data->n_vals)
++        return -1;
++
++    if(scatt_data->b_conds_arr)
++        scatt_data->b_conds_arr[val_idx] = val;
++    else if(scatt_data->scatt_vals_arr)
++        scatt_data->scatt_vals_arr[val_idx] = val;
++    else
++        return -1;
++
++    return 0;
++}
++#endif



More information about the grass-commit mailing list