[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