[GRASS-SVN] r47463 - grass/trunk/gui/wxpython/gui_modules

svn_grass at osgeo.org svn_grass at osgeo.org
Fri Aug 5 14:39:16 EDT 2011


Author: annakrat
Date: 2011-08-05 11:39:15 -0700 (Fri, 05 Aug 2011)
New Revision: 47463

Modified:
   grass/trunk/gui/wxpython/gui_modules/colorrules.py
   grass/trunk/gui/wxpython/gui_modules/nviz_mapdisp.py
   grass/trunk/gui/wxpython/gui_modules/nviz_tools.py
   grass/trunk/gui/wxpython/gui_modules/preferences.py
   grass/trunk/gui/wxpython/gui_modules/workspace.py
   grass/trunk/gui/wxpython/gui_modules/wxnviz.py
Log:
wxNviz: first and imperfect implementation of thematic mapping (only color so far) for points

Modified: grass/trunk/gui/wxpython/gui_modules/colorrules.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/colorrules.py	2011-08-05 13:52:49 UTC (rev 47462)
+++ grass/trunk/gui/wxpython/gui_modules/colorrules.py	2011-08-05 18:39:15 UTC (rev 47463)
@@ -36,18 +36,21 @@
 import menuform
 from debug import Debug as Debug
 from preferences import globalSettings as UserSettings
+from nviz_mapdisp import wxUpdateProperties
 
 class ColorTable(wx.Frame):
-    def __init__(self, parent, raster, id = wx.ID_ANY, title = _("Set color table"),
+    def __init__(self, parent, raster, nviz = False, id = wx.ID_ANY, title = _("Set color table"),
                  style = wx.DEFAULT_FRAME_STYLE | wx.RESIZE_BORDER,
                  **kwargs):
         """!Dialog for interactively entering rules for map management
         commands
 
         @param raster True to raster otherwise vector
+        @param nviz True if ColorTable is called from nviz thematic mapping
         """
         self.parent = parent # GMFrame
         self.raster = raster
+        self.nviz = nviz # called from nviz - thematic mapping
         
         wx.Frame.__init__(self, parent, id, title, style = style, **kwargs)
         
@@ -94,8 +97,7 @@
         if self.raster:
             self.SetTitle(_('Create new color table for raster map'))
         else:
-            self.SetTitle(_('Create new color table for vector map'))
-            
+            self.SetTitle(_('Create new color table for vector map'))    
         # layout
         self.__doLayout()
         
@@ -117,28 +119,32 @@
             self.Bind(wx.EVT_COMBOBOX, self.OnColumnSelection, self.cb_vcol)
             self.Bind(wx.EVT_COMBOBOX, self.OnRGBColSelection, self.cb_vrgb)
             self.Bind(wx.EVT_BUTTON, self.OnAddColumn, self.btn_addCol)
+        if not self.nviz:
+            # set map layer from layer tree, first selected,
+            # if not the right type, than select another
+            if self.raster:
+                elem = 'raster'
+            else:
+                elem = 'vector'
+            try:
+                sel = self.parent.curr_page.maptree.layer_selected
+                if sel and self.parent.curr_page.maptree.GetPyData(sel)[0]['type'] == elem:
+                    layer = sel
+                else:
+                    layer = self.parent.curr_page.maptree.FindItemByData(key = 'type', value = elem)
+            except:
+                layer = None
+            if layer:
+                mapLayer = self.parent.curr_page.maptree.GetPyData(layer)[0]['maplayer']
+                name = mapLayer.GetName()
+                type = mapLayer.GetType()
+                self.selectionInput.SetValue(name)
+                self.inmap = name
+        else:
+            self.inmap = self.parent.GetLayerData(nvizType = 'vector', nameOnly = True)
+            self.OnSelectionInput(None)
+            self.nvizInfo.SetLabel(_("Set color rules for vector map %s:") % self.inmap)
             
-        # set map layer from layer tree, first selected,
-        # if not the right type, than select another
-        if self.raster:
-            elem = 'raster'
-        else:
-            elem = 'vector'
-        try:
-            sel = self.parent.curr_page.maptree.layer_selected
-            if sel and self.parent.curr_page.maptree.GetPyData(sel)[0]['type'] == elem:
-                layer = sel
-            else:
-                layer = self.parent.curr_page.maptree.FindItemByData(key = 'type', value = elem)
-        except:
-            layer = None
-        if layer:
-            mapLayer = self.parent.curr_page.maptree.GetPyData(layer)[0]['maplayer']
-            name = mapLayer.GetName()
-            type = mapLayer.GetType()
-            self.selectionInput.SetValue(name)
-            self.inmap = name
-        
         self.SetMinSize(self.GetSize())
         
         self.CentreOnScreen()
@@ -202,6 +208,9 @@
         self.btn_addCol.SetToolTipString(_("Add GRASSRGB column to current attribute table."))
         
         # layout
+        inputBox = wx.StaticBox(parent = self, id = wx.ID_ANY,
+                                label = " %s " % _("Select vector columns"))
+        inputSizer = wx.StaticBoxSizer(inputBox, wx.VERTICAL)
         vSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
         vSizer.Add(self.cb_vl_label, pos = (0, 0),
                    flag = wx.ALIGN_CENTER_VERTICAL)
@@ -217,8 +226,10 @@
                    flag = wx.ALIGN_CENTER_VERTICAL)
         vSizer.Add(self.btn_addCol, pos = (2, 2),
                    flag = wx.ALIGN_CENTER_VERTICAL)
+        inputSizer.Add(item = vSizer,
+                       flag = wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.EXPAND, border = 5)
                 
-        return vSizer
+        return inputSizer
     
     def _createColorRulesPanel(self):
         """!Create rules panel"""
@@ -275,6 +286,16 @@
         mapSelection = self._createMapSelection()
         sizer.Add(item = mapSelection, proportion = 0,
                   flag = wx.ALL | wx.EXPAND, border = 5)
+        if self.nviz:
+            sizerNviz = wx.BoxSizer(wx.HORIZONTAL)
+            self.nvizInfo = wx.StaticText(parent = self, id = wx.ID_ANY,
+                                 label = _('')) # set later
+            sizerNviz.Add(self.nvizInfo, proportion = 0, flag = wx.LEFT | wx.EXPAND, border = 0)
+            sizer.Add(item = sizerNviz, proportion = 0,
+                  flag = wx.LEFT | wx.BOTTOM | wx.EXPAND, border = 5)
+            sizer.Hide(mapSelection)
+            # doesn't work
+            sizer.Layout()
         #
         # set vector attributes
         #
@@ -345,6 +366,7 @@
                   flag = wx.ALL | wx.ALIGN_RIGHT, border = 5)
         
         self.SetSizer(sizer)
+        sizer.Layout()
         sizer.Fit(self)
         self.Layout()
         
@@ -588,9 +610,9 @@
                 except ValueError:
                     self.properties['min'] = self.properties['max'] = ''
                     
-        if self.properties['min'] and self.properties['max']:
+        if self.properties['min'] or self.properties['max']:
             if ctype == int:
-                self.cr_label.SetLabel(_("Enter vector attribute values or ranges (type: %s, range: %d - %d )")
+                self.cr_label.SetLabel(_("Enter vector attribute values or ranges (type: %s, range: %d - %d)")
                             % (type, self.properties['min'], self.properties['max']))
             elif ctype == float:
                 self.cr_label.SetLabel(_("Enter vector attribute values or ranges (type: %s, range: %.1f - %.1f )")
@@ -729,10 +751,22 @@
         @return True on success otherwise False
         """
         ret = self.CreateColorTable()
-        display = self.parent.GetLayerTree().GetMapDisplay()
-        if display and display.IsAutoRendered():
-            display.GetWindow().UpdateMap(render = True)
-        
+        if not ret:
+            GMessage(parent = self, message = _("No color rules given."))
+            
+        if not self.nviz:
+            display = self.parent.GetLayerTree().GetMapDisplay()
+            if display and display.IsAutoRendered():
+                display.GetWindow().UpdateMap(render = True)
+        else:
+            data = self.parent.GetLayerData(nvizType = 'vector')
+            data['vector']['points']['thematic']['layer'] = int(self.properties['layer'])
+            data['vector']['points']['thematic']['rgbcolumn'] = self.properties['rgb']
+            data['vector']['points']['thematic']['update'] = None
+            
+            event = wxUpdateProperties(data = data)
+            wx.PostEvent(self.parent.mapWindow, event)
+            self.parent.mapWindow.Refresh(False)
         return ret
 
     def OnOK(self, event):

Modified: grass/trunk/gui/wxpython/gui_modules/nviz_mapdisp.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/nviz_mapdisp.py	2011-08-05 13:52:49 UTC (rev 47462)
+++ grass/trunk/gui/wxpython/gui_modules/nviz_mapdisp.py	2011-08-05 18:39:15 UTC (rev 47463)
@@ -1563,6 +1563,7 @@
                 'update' in data['width'] or \
                 'update' in data['marker'] or \
                 'update' in data['color']:
+                
             ret = self._display.SetVectorPointMode(id, data['color']['value'],
                                                    data['width']['value'], float(data['size']['value']),
                                                    data['marker']['value'] + 1)
@@ -1586,6 +1587,16 @@
                                                data['height']['value'])
             data['height'].pop('update')
         
+        # thematic
+        if 'update' in data['thematic']:
+            if data['thematic']['use']:
+                self._display.SetStyleThematic(id = id, layer = data['thematic']['layer'],
+                                               color = data['thematic']['rgbcolumn'],
+                                               size = data['thematic']['sizecolumn'])
+            else:
+                self._display.UnsetStyleThematic(id = id, layer = data['thematic']['layer'])
+            data['thematic'].pop('update')
+            
         # surface
         if 'update' in data['mode']:
             for item in range(len(data['mode']['surface']['value'])):
@@ -1599,7 +1610,7 @@
                             self._display.UnsetVectorPointSurface(id, sid)   
                         break
             data['mode'].pop('update')
-   
+            
     def GetLayerNames(self, type):
         """!Return list of map layer names of given type"""
         layerName = []

Modified: grass/trunk/gui/wxpython/gui_modules/nviz_tools.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/nviz_tools.py	2011-08-05 13:52:49 UTC (rev 47462)
+++ grass/trunk/gui/wxpython/gui_modules/nviz_tools.py	2011-08-05 18:39:15 UTC (rev 47463)
@@ -46,6 +46,7 @@
 import globalvar
 import gselect
 import gcmd
+import colorrules
 from preferences import globalSettings as UserSettings
 try:
     from nviz_mapdisp import wxUpdateView, wxUpdateLight, wxUpdateProperties,\
@@ -1207,8 +1208,12 @@
         box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
                             label = " %s " % (_("Vector points")))
         boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+        vertSizer = wx.BoxSizer(wx.VERTICAL)
         gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
-        gridSizer.AddGrowableCol(5)
+        gridSizer.AddGrowableCol(0)
+        gridSizer.AddGrowableCol(2)
+        gridSizer.AddGrowableCol(4)
+        gridSizer.AddGrowableCol(6)
         
         # icon size
         gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
@@ -1246,51 +1251,69 @@
                       wx.ALIGN_LEFT,
                       pos = (0, 4))
 
-        # icon width
-        gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
-                                           label = _("width")),
-                      pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL |
-                      wx.ALIGN_RIGHT)
-        
-        iwidth = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
-                             initial = 1,
-                             min = 1,
-                             max = 1e6)
-        iwidth.SetName('value')
-        iwidth.SetValue(100)
-        self.win['vector']['points']['width'] = iwidth.GetId()
-        iwidth.Bind(wx.EVT_SPINCTRL, self.OnVectorPoints)
-        iwidth.Bind(wx.EVT_TEXT, self.OnVectorPoints)
-        gridSizer.Add(item = iwidth, pos = (1, 2),
-                      flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
+        # icon width - seems to do nothing
+##        gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+##                                           label = _("width")),
+##                      pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL |
+##                      wx.ALIGN_RIGHT)
+##        
+##        iwidth = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
+##                             initial = 1,
+##                             min = 1,
+##                             max = 1e6)
+##        iwidth.SetName('value')
+##        iwidth.SetValue(100)
+##        self.win['vector']['points']['width'] = iwidth.GetId()
+##        iwidth.Bind(wx.EVT_SPINCTRL, self.OnVectorPoints)
+##        iwidth.Bind(wx.EVT_TEXT, self.OnVectorPoints)
+##        gridSizer.Add(item = iwidth, pos = (1, 2),
+##                      flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
         # icon symbol
         gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
                                          label = _("symbol:")),
-                      pos = (1, 3), flag = wx.ALIGN_CENTER_VERTICAL)
+                      pos = (0, 5), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
         isym = wx.Choice (parent = panel, id = wx.ID_ANY, size = (100, -1),
                           choices = UserSettings.Get(group = 'nviz', key = 'vector',
                                                    subkey = ['points', 'marker'], internal = True))
         isym.SetName("selection")
         self.win['vector']['points']['marker'] = isym.GetId()
         isym.Bind(wx.EVT_CHOICE, self.OnVectorPoints)
-        gridSizer.Add(item = isym, flag = wx.ALIGN_CENTER_VERTICAL,
-                      pos = (1, 4))
+        gridSizer.Add(item = isym, flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT,
+                      pos = (0, 6))
+        # thematic mapping
+        self.win['vector']['points']['thematic'] = {}
+        checkThematic = wx.CheckBox(parent = panel, id = wx.ID_ANY,
+                                         label = _("use thematic mapping for vector points"))
+        self.win['vector']['points']['thematic']['check'] = checkThematic.GetId()
+        checkThematic.Bind(wx.EVT_CHECKBOX, self.OnCheckThematic)
+        checkThematic.SetValue(False)
         
+        gridSizer.Add(item = checkThematic, flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT,
+                      pos = (1, 1), span = (1, 5))
+        setThematic = wx.Button(parent = panel, id = wx.ID_ANY,
+                                         label = _("Set options..."))
+        self.win['vector']['points']['thematic']['button'] = setThematic.GetId()
+        setThematic.Bind(wx.EVT_BUTTON, self.OnSetThematic)
+        gridSizer.Add(item = setThematic, flag = wx.ALIGN_CENTER_VERTICAL,
+                      pos = (1, 6))
+                           
+        vertSizer.Add(gridSizer, proportion = 0, flag = wx.EXPAND, border = 0)
         # high
+        gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
+        gridSizer.AddGrowableCol(1)
         gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
                                          label = _("Display on surface(s):")),
-                      pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL,
-                      span = (1, 5))
+                      pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
         gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
                                          label = _("Height above surface:")),
-                      pos = (3, 5), flag = wx.ALIGN_CENTER_VERTICAL)
+                      pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL)
         
         surface = wx.CheckListBox(parent = panel, id = wx.ID_ANY, size = (-1, 60),
                                   choices = [], style = wx.LB_NEEDED_SB)
         surface.Bind(wx.EVT_CHECKLISTBOX, self.OnVectorSurface)
         self.win['vector']['points']['surface'] = surface.GetId()
         gridSizer.Add(item = surface, 
-                      pos = (3, 0), span = (3, 5),
+                      pos = (1, 0), span = (3, 1),
                       flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
         
         self._createControl(panel, data = self.win['vector']['points'], name = 'height', size = -1,
@@ -1301,12 +1324,13 @@
         self.FindWindowById(self.win['vector']['points']['height']['text']).SetValue(0)
         
         gridSizer.Add(item = self.FindWindowById(self.win['vector']['points']['height']['slider']),
-                      pos = (4, 5),flag = wx.EXPAND|wx.ALIGN_CENTER_VERTICAL)
+                      pos = (2, 1),flag = wx.EXPAND|wx.ALIGN_CENTER_VERTICAL)
         gridSizer.Add(item = self.FindWindowById(self.win['vector']['points']['height']['text']),
-                      pos = (5, 5),
+                      pos = (3, 1),
                       flag = wx.ALIGN_CENTER)
-        
-        boxSizer.Add(item = gridSizer, proportion = 1,
+                    
+        vertSizer.Add(gridSizer, proportion = 0, flag = wx.EXPAND, border = 0)
+        boxSizer.Add(item = vertSizer, proportion = 1,
                      flag = wx.ALL | wx.EXPAND, border = 3)
         pageSizer.Add(item = boxSizer, proportion = 0,
                       flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
@@ -1827,9 +1851,11 @@
 
         return panel
     
-    def GetLayerData(self, nvizType):
+    def GetLayerData(self, nvizType, nameOnly = False):
         """!Get nviz data"""
         name = self.FindWindowById(self.win[nvizType]['map']).GetValue()
+        if nameOnly:
+            return name
         
         if nvizType == 'surface' or nvizType == 'fringe':
             return self.mapWindow.GetLayerByName(name, mapType = 'raster', dataType = 'nviz')
@@ -3158,6 +3184,33 @@
         if self.mapDisplay.statusbarWin['render'].IsChecked():
             self.mapWindow.Refresh(False)
 
+    def OnCheckThematic(self, event):
+        """!Switch on/off thematic mapping"""
+        check = self.win['vector']['points']['thematic']['check']
+        button = self.win['vector']['points']['thematic']['button']
+        if self.FindWindowById(check).GetValue():
+            checked = True
+        else:
+            checked = False
+        self.FindWindowById(button).Enable(checked)
+        
+        data = self.GetLayerData('vector')
+        data['vector']['points']['thematic']['use'] = checked
+        data['vector']['points']['thematic']['update'] = None
+        
+        # update properties
+        event = wxUpdateProperties(data = data)
+        wx.PostEvent(self.mapWindow, event)
+        
+        if self.mapDisplay.statusbarWin['render'].IsChecked():
+            self.mapWindow.Refresh(False)
+            
+    def OnSetThematic(self, event):
+        """!Set options for thematic points"""
+        ctable = colorrules.ColorTable(self, raster = False, nviz = True)
+        ctable.CentreOnScreen()
+        ctable.Show()
+        
     def UpdateIsosurfButtons(self, list):
         """!Enable/disable buttons 'add', 'delete',
         'move up', 'move down'"""
@@ -4251,6 +4304,7 @@
                 win.SetValue(color)
             else:
                 win.SetValue(data['points'][prop]['value'])
+        self.OnCheckThematic(None)
         # height
         for type in ('slider', 'text'):
             win = self.FindWindowById(self.win['vector']['points']['height'][type])

Modified: grass/trunk/gui/wxpython/gui_modules/preferences.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/preferences.py	2011-08-05 13:52:49 UTC (rev 47462)
+++ grass/trunk/gui/wxpython/gui_modules/preferences.py	2011-08-05 18:39:15 UTC (rev 47463)
@@ -533,6 +533,8 @@
                         'marker' : 2,
                         'color' : (0, 0, 255, 255), # blue
                         'height' : 0,
+                        'rgbcolumn': None,
+                        'sizecolumn': None,
                         }
                     },
                 'volume' : {

Modified: grass/trunk/gui/wxpython/gui_modules/workspace.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/workspace.py	2011-08-05 13:52:49 UTC (rev 47462)
+++ grass/trunk/gui/wxpython/gui_modules/workspace.py	2011-08-05 18:39:15 UTC (rev 47463)
@@ -480,10 +480,12 @@
         iview['twist']['max'] = self.__processLayerNvizNode(node_twist, 'max', int)
         node_zexag = node_view.find('z-exag')
         view['z-exag'] = {}
+        iview['z-exag'] = {}
         view['z-exag']['value'] = self.__processLayerNvizNode(node_zexag, 'value', int)
         view['z-exag']['step'] = self.__processLayerNvizNode(node_zexag, 'step', int)
         view['z-exag']['min'] = self.__processLayerNvizNode(node_zexag, 'min', int)
         view['z-exag']['max'] = self.__processLayerNvizNode(node_zexag, 'max', int)
+        iview['z-exag']['original'] = self.__processLayerNvizNode(node_zexag, 'original', float)
         node_focus = node_view.find('focus')
         iview['focus'] = {}
         iview['focus']['x'] = self.__processLayerNvizNode(node_focus, 'x', int)
@@ -735,10 +737,16 @@
         # height
         data['height'] = { 'value' : UserSettings.Get(group='nviz', key='vector',
                                                       subkey=['points', 'height']) }
-
+        
+        data['thematic'] = {'rgbcolumn' : UserSettings.Get(group='nviz', key='vector',
+                                                      subkey=['points', 'rgbcolumn']),
+                            'sizecolumn' : UserSettings.Get(group='nviz', key='vector',
+                                                      subkey=['points', 'sizecolumn']),
+                            'layer': 1,
+                            'use' : False}
         if 'object' in data:
             for attrb in ('size', 'width', 'marker',
-                          'color', 'surface', 'height'):
+                          'color', 'surface', 'height', 'thematic'):
                 data[attrb]['update'] = None
         
     def GetDrawMode(self, mode=None, style=None, shade=None, string=False):
@@ -1109,7 +1117,7 @@
                                                            marker))
             self.indent += 4
             for name in data[attrb].iterkeys():
-                if name in ('object', 'marker'):
+                if name in ('object', 'marker', 'thematic'):
                     continue
                 if name == 'mode':
                     self.file.write('%s<%s type="%s">\n' % (' ' * self.indent, name,
@@ -1193,6 +1201,7 @@
         self.file.write('%s<step>%d</step>\n' % (' ' * self.indent, view['z-exag']['step']))
         self.file.write('%s<min>%d</min>\n' % (' ' * self.indent, view['z-exag']['min']))
         self.file.write('%s<max>%d</max>\n' % (' ' * self.indent, view['z-exag']['max']))
+        self.file.write('%s<original>%d</original>\n' % (' ' * self.indent, iview['z-exag']['original']))
         self.indent -= 4
         self.file.write('%s</z-exag>\n' % (' ' * self.indent))
         # focus (look here)

Modified: grass/trunk/gui/wxpython/gui_modules/wxnviz.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/wxnviz.py	2011-08-05 13:52:49 UTC (rev 47462)
+++ grass/trunk/gui/wxpython/gui_modules/wxnviz.py	2011-08-05 18:39:15 UTC (rev 47463)
@@ -940,6 +940,15 @@
         
         return 1
 
+    def SetStyleThematic(self, id, layer, color = None, width = None, size = None, symbol = None):
+        """!Set thematic style for vector points"""
+        GP_set_style_thematic(id, layer, color, width, size, symbol)
+        
+    def UnsetStyleThematic(self, id, layer):
+        """!Set thematic style None for vector points"""
+        # this should be done in another way
+        GP_set_style_thematic(id, layer, None, None, None, None)
+        
     def UnsetVectorPointSurface(self, id, surf_id):
         """!Unset reference surface of vector set (points)
         



More information about the grass-commit mailing list