[GRASS-SVN] r32926 - in grass/branches/develbranch_6/gui/wxpython: gui_modules vdigit

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Aug 20 14:03:58 EDT 2008


Author: martinl
Date: 2008-08-20 14:03:58 -0400 (Wed, 20 Aug 2008)
New Revision: 32926

Modified:
   grass/branches/develbranch_6/gui/wxpython/gui_modules/dbm.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz_mapdisp.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/render.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/vdigit.py
   grass/branches/develbranch_6/gui/wxpython/vdigit/cats.cpp
   grass/branches/develbranch_6/gui/wxpython/vdigit/driver.cpp
   grass/branches/develbranch_6/gui/wxpython/vdigit/driver.h
   grass/branches/develbranch_6/gui/wxpython/vdigit/line.cpp
   grass/branches/develbranch_6/gui/wxpython/vdigit/vertex.cpp
Log:
wxGUI: (atm) "display selected" & "display selected and zoom" can be used also when vector layer is edited
(nviz): run nviz extension in different thread


Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/dbm.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/dbm.py	2008-08-20 14:02:24 UTC (rev 32925)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/dbm.py	2008-08-20 18:03:58 UTC (rev 32926)
@@ -894,6 +894,7 @@
             self.popupDataID7 = wx.NewId()
             self.popupDataID8 = wx.NewId()
             self.popupDataID9 = wx.NewId()
+            self.popupDataID10 = wx.NewId()
 
             self.Bind(wx.EVT_MENU, self.OnDataItemEdit,       id=self.popupDataID1)
             self.Bind(wx.EVT_MENU, self.OnDataItemAdd,        id=self.popupDataID2)
@@ -902,8 +903,9 @@
             self.Bind(wx.EVT_MENU, self.OnDataSelectAll,      id=self.popupDataID5)
             self.Bind(wx.EVT_MENU, self.OnDataSelectNone,     id=self.popupDataID6)
             self.Bind(wx.EVT_MENU, self.OnDataDrawSelected,   id=self.popupDataID7)
-            self.Bind(wx.EVT_MENU, self.OnExtractSelected,    id=self.popupDataID8)
-            self.Bind(wx.EVT_MENU, self.OnDataReload,         id=self.popupDataID9)
+            self.Bind(wx.EVT_MENU, self.OnDataDrawSelectedZoom, id=self.popupDataID8)
+            self.Bind(wx.EVT_MENU, self.OnExtractSelected,    id=self.popupDataID9)
+            self.Bind(wx.EVT_MENU, self.OnDataReload,         id=self.popupDataID10)
 
         list = self.FindWindowById(self.layerPage[self.layer]['data'])
         # generate popup-menu
@@ -920,14 +922,16 @@
         menu.Append(self.popupDataID6, _("Deselect all"))
         menu.AppendSeparator()
         menu.Append(self.popupDataID7, _("Display selected"))
+        menu.Append(self.popupDataID8, _("Display selected and zoom"))
         if not self.map or len(list.GetSelectedItems()) == 0:
             menu.Enable(self.popupDataID7, False)
-        menu.Append(self.popupDataID8, _("Extract selected"))
+            menu.Enable(self.popupDataID8, False)
+        menu.Append(self.popupDataID9, _("Extract selected"))
         if list.GetFirstSelected() == -1:
             menu.Enable(self.popupDataID3, False)
-            menu.Enable(self.popupDataID8, False)
+            menu.Enable(self.popupDataID9, False)
         menu.AppendSeparator()
-        menu.Append(self.popupDataID9, _("Reload"))
+        menu.Append(self.popupDataID10, _("Reload"))
 
         self.PopupMenu(menu)
         menu.Destroy()
@@ -1025,15 +1029,40 @@
         
         event.Skip()
 
+    def _drawSelected(self, zoom):
+        """Highlight selected features"""
+        if not self.map or not self.mapdisplay:
+            return
+
+        digitToolbar = self.mapdisplay.toolbars['vdigit']
+        if digitToolbar and \
+                digitToolbar.GetLayer().GetName() == self.vectmap:
+            list = self.FindWindowById(self.layerPage[self.layer]['data'])
+            cats = map(int, list.GetSelectedItems())
+            self.mapdisplay.digit.driver.SetSelected(cats, cats=True)
+            if zoom:
+                n, s, w, e = self.mapdisplay.digit.driver.GetRegionSelected()
+                self.mapdisplay.Map.GetRegion(n=n, s=s, w=w, e=e,
+                                              update=True)
+                self.mapdisplay.Map.AdjustRegion() # resolution
+                self.mapdisplay.MapWindow.UpdateMap(render=True, renderVector=True)
+            else:
+                self.mapdisplay.MapWindow.UpdateMap(render=False, renderVector=True)
+        else:
+            # add map layer with higlighted vector features
+            self.AddQueryMapLayer()
+            self.mapdisplay.MapWindow.UpdateMap(render=False, renderVector=False,
+                                                zoom=zoom)
+        
     def OnDataDrawSelected(self, event):
         """Reload table description"""
-        if self.map and self.mapdisplay:
-            # add map layer with higlighted vector features
-            self.AddQueryMapLayer()
-            self.mapdisplay.MapWindow.UpdateMap(render=False, renderVector=False)
+        self._drawSelected(zoom=False)
+        event.Skip()
 
+    def OnDataDrawSelectedZoom(self, event):
+        self._drawSelected(zoom=True)
         event.Skip()
-
+        
     def OnDataItemAdd(self, event):
         """Add new record to the attribute table"""
         list      = self.FindWindowById(self.layerPage[self.layer]['data'])

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp.py	2008-08-20 14:02:24 UTC (rev 32925)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp.py	2008-08-20 18:03:58 UTC (rev 32926)
@@ -612,13 +612,14 @@
 
         return img
 
-    def UpdateMap(self, render=True, renderVector=True):
+    def UpdateMap(self, render=True, renderVector=True, zoom=False):
         """
         Updates the canvas anytime there is a change to the
         underlaying images or to the geometry of the canvas.
 
         @param render re-render map composition
         @param renderVector re-render vector map layer enabled for editing (used for digitizer)
+        @param zoom zoom to region given by 'd.vect -r'
         """
         start = time.clock()
 
@@ -656,9 +657,11 @@
             if self.parent.compResolution.GetValue():
                 # use computation region resolution for rendering
                 windres = True
-            self.mapfile = self.Map.Render(force=True, mapWindow=self.parent, windres=windres)
+            self.mapfile = self.Map.Render(force=True, mapWindow=self.parent,
+                                           windres=windres, zoom=zoom)
         else:
-            self.mapfile = self.Map.Render(force=False, mapWindow=self.parent)
+            self.mapfile = self.Map.Render(force=False, mapWindow=self.parent,
+                                           zoom=zoom)
             
         self.img = self.GetImage() # id=99
             
@@ -3369,6 +3372,7 @@
         str(color[2])
 
         cmd = ["d.vect",
+               #               "-r", # print minimal region extent
                "map=%s" % name,
                "color=%s" % colorStr,
                "fcolor=%s" % colorStr,

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz_mapdisp.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz_mapdisp.py	2008-08-20 14:02:24 UTC (rev 32925)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz_mapdisp.py	2008-08-20 18:03:58 UTC (rev 32926)
@@ -34,6 +34,7 @@
 from debug import Debug as Debug
 from preferences import globalSettings as UserSettings
 from mapdisp import MapWindow as MapWindow
+from goutput import wxCmdOutput as wxCmdOutput
 
 sys.path.append(os.path.join(globalvar.ETCWXDIR, "nviz"))
 import grass6_wxnviz as wxnviz
@@ -41,6 +42,22 @@
 wxUpdateProperties, EVT_UPDATE_PROP = NewEvent()
 wxUpdateView,       EVT_UPDATE_VIEW = NewEvent()
 
+class NvizThread(Thread):
+    def __init__(self, log, progressbar, window):
+        Thread.__init__(self)
+        
+        self.log = log
+        self.progressbar = progressbar
+        self.window = window
+        
+        self.nvizClass = None
+        
+        self.setDaemon(True)
+        
+    def run(self):
+        self.nvizClass = wxnviz.Nviz(self.log, self.progressbar,
+                                     self.window, wxCmdOutput)
+        
 class GLWindow(MapWindow, glcanvas.GLCanvas):
     """OpenGL canvas for Map Display Window"""
     def __init__(self, parent, id,
@@ -78,7 +95,12 @@
         #
         # create nviz instance
         #
-        self.nvizClass = wxnviz.Nviz(sys.stderr)
+        self.nvizThread = NvizThread(self.gismgr.goutput.cmd_stderr,
+                                     self.parent.onRenderGauge,
+                                     self.gismgr.goutput.cmd_output)
+        self.nvizThread.start()
+        time.sleep(.1)
+        self.nvizClass =  self.nvizThread.nvizClass
 
         #
         # set current display

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/render.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/render.py	2008-08-20 14:02:24 UTC (rev 32925)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/render.py	2008-08-20 18:03:58 UTC (rev 32926)
@@ -76,6 +76,8 @@
         self.hidden  = hidden
         self.opacity = opacity
 
+        self._region = None # produced by `d.vect -r`
+        
         self.force_render = True
         
         Debug.msg (3, "Layer.__init__(): type=%s, cmd='%s', name=%s, " \
@@ -95,12 +97,16 @@
         Debug.msg (3, "Layer.__del__(): layer=%s, cmd='%s'" %
                    (self.name, self.GetCmd(string=True)))
 
-    def Render(self):
+    def Render(self, zoom):
         """Render layer to image
 
+        @param zoom if True zoom to extent given by 'd.vect -r'
+        
         @return rendered image filename
         @return None on error
         """
+        self._region = None # reset region
+
         if len(self.cmdlist) == 0:
             return None
         
@@ -144,20 +150,32 @@
             runcmd = gcmd.Command(cmd=self.cmdlist + ['--q'],
                                   stderr=None)
 
+            if zoom:
+                self._region = {}
+                for line in runcmd.ReadStdOutput():
+                    key, value = line.split('=')
+                    self._region[key] = float(value)
+                    
             if runcmd.returncode != 0:
                 #clean up after probley
-                os.remove(self.mapfile)
-                os.remove(self.maskfile)
-                os.remove(self.gtemp)
+                try:
+                    os.remove(self.mapfile)
+                    os.remove(self.maskfile)
+                    os.remove(self.gtemp)
+                except (OSError, TypeError):
+                    pass
                 self.mapfile = None
                 self.maskfile = None
 
         except gcmd.CmdError, e:
             print >> sys.stderr, e
-            #clean up after probley
-            os.remove(self.mapfile)
-            os.remove(self.maskfile)
-            os.remove(self.gtemp)
+            # clean up after problems
+            try:
+                os.remove(self.mapfile)
+                os.remove(self.maskfile)
+                os.remove(self.gtemp)
+            except (OSError, TypeError):
+                pass
             self.mapfile = None
             self.maskfile = None
 
@@ -264,7 +282,11 @@
 
         # for re-rendering
         self.force_render = True
-        
+
+    def GetRegion(self):
+        """Get layer region or None"""
+        return self._region
+    
 class MapLayer(Layer):
     """Represents map layer in the map canvas"""
     def __init__(self, type, cmd, name=None,
@@ -536,7 +558,8 @@
             return False
 
     def GetRegion(self, rast=None, zoom=False, vect=None,
-                  n=None, s=None, e=None, w=None, default=False):
+                  n=None, s=None, e=None, w=None, default=False,
+                  update=False):
         """
         Get region settings (g.region -upgc)
 
@@ -547,6 +570,7 @@
         @param zoom zoom to raster (ignore NULLs)
         @param n,s,e,w force extent
         @param default force default region settings
+        @param update if True update current display region settings
         
         @return region settings as directory, e.g. {
         'n':'4928010', 's':'4913700', 'w':'589980',...}
@@ -616,6 +640,9 @@
 
         Debug.msg (3, "Map.GetRegion(): %s" % region)
         
+        if update:
+            self.region = region
+        
         return region
 
     def GetCurrentRegion(self):
@@ -782,7 +809,48 @@
 
         return selected
 
-    def Render(self, force=False, mapWindow=None, windres=False):
+    def _renderLayers(self, force, zoom, mapWindow, maps, masks, opacities):
+        # render map layers
+        ilayer = 1
+        for layer in self.layers + self.overlays:
+            # skip dead or disabled map layers
+            if layer == None or layer.active == False:
+                continue
+            
+            # render if there is no mapfile
+            if force or \
+               layer.force_render or \
+               layer.mapfile == None or \
+               (not os.path.isfile(layer.mapfile) or not os.path.getsize(layer.mapfile)):
+                if not layer.Render(zoom):
+                    continue
+            
+            zoomToRegion = layer.GetRegion()
+            if zoomToRegion:
+                self.GetRegion(n=zoomToRegion['n'], s=zoomToRegion['s'],
+                               w=zoomToRegion['w'], e=zoomToRegion['e'],
+                               update=True)
+                self.AdjustRegion() # resolution
+                print self.region
+                return False
+            
+            # update progress bar
+            wx.SafeYield(mapWindow)
+            event = wxUpdateProgressBar(value=ilayer)
+            wx.PostEvent(mapWindow, event)
+            
+            # add image to compositing list
+            if layer.type != "overlay":
+                maps.append(layer.mapfile)
+                masks.append(layer.maskfile)
+                opacities.append(str(layer.opacity))
+                
+            Debug.msg (3, "Map.Render() type=%s, layer=%s " % (layer.type, layer.name))
+            ilayer += 1
+
+        return True
+    
+    def Render(self, force=False, mapWindow=None, windres=False, zoom=False):
         """
         Creates final image composite
 
@@ -792,10 +860,10 @@
         @param force force rendering
         @param reference for MapFrame instance (for progress bar)
         @param windres use region resolution (True) otherwise display resolution
-
+        @param zoom zoom to region given by 'd.vect -r'
+        
         @return name of file with rendered image or None
         """
-
         maps = []
         masks =[]
         opacities = []
@@ -817,36 +885,11 @@
             os.environ["GRASS_COMPRESSION"] = "0"
             os.environ["GRASS_TRUECOLOR"] = "TRUE"
             os.environ["GRASS_RENDER_IMMEDIATE"] = "TRUE"
-
-        # render map layers
-        ilayer = 1
-        for layer in self.layers + self.overlays:
-            # skip dead or disabled map layers
-            if layer == None or layer.active == False:
-                continue
-            
-            # render if there is no mapfile
-            if force or \
-               layer.force_render or \
-               layer.mapfile == None or \
-               (not os.path.isfile(layer.mapfile) or not os.path.getsize(layer.mapfile)):
-                if not layer.Render():
-                    continue
-            
-            # update progress bar
-            wx.SafeYield(mapWindow)
-            event = wxUpdateProgressBar(value=ilayer)
-            wx.PostEvent(mapWindow, event)
-            
-            # add image to compositing list
-            if layer.type != "overlay":
-                maps.append(layer.mapfile)
-                masks.append(layer.maskfile)
-                opacities.append(str(layer.opacity))
-                
-            Debug.msg (3, "Map.Render() type=%s, layer=%s " % (layer.type, layer.name))
-            ilayer += 1
         
+        if not self._renderLayers(force, zoom, mapWindow, maps, masks, opacities):
+            os.environ["GRASS_REGION"] = self.SetRegion(windres)
+            self._renderLayers(True, False, mapWindow, maps, masks, opacities)
+        
         # ugly hack for MSYS
         if not subprocess.mswindows:
             mapstr = ",".join(maps)

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/vdigit.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/vdigit.py	2008-08-20 14:02:24 UTC (rev 32925)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/vdigit.py	2008-08-20 18:03:58 UTC (rev 32926)
@@ -1419,6 +1419,10 @@
             
         return selected
 
+    def GetRegionSelected(self):
+        """Get minimal region extent of selected features (ids/cats)"""
+        return self.__display.GetRegionSelected()
+    
     def GetDuplicates(self):
         """Return ids of (selected) duplicated vector features
         """
@@ -1465,15 +1469,16 @@
 
         return id 
 
-    def SetSelected(self, id):
+    def SetSelected(self, id, cats=False):
         """Set selected vector features
 
         @param id line id to be selected
+        @param cats if True expect categories instead of feature ids
         """
         Debug.msg(4, "CDisplayDriver.SetSelected(): id=%s" % \
                   ",".join(["%d" % v for v in id]))
 
-        self.__display.SetSelected(id)
+        self.__display.SetSelected(id, cats)
 
     def UnSelect(self, id):
         """Unselect vector features

Modified: grass/branches/develbranch_6/gui/wxpython/vdigit/cats.cpp
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/vdigit/cats.cpp	2008-08-20 14:02:24 UTC (rev 32925)
+++ grass/branches/develbranch_6/gui/wxpython/vdigit/cats.cpp	2008-08-20 18:03:58 UTC (rev 32926)
@@ -161,13 +161,13 @@
 	return lc;
     }
 
-    if (line_id == -1 && display->selected->n_values < 1) {
+    if (line_id == -1 && display->selected.values->n_values < 1) {
 	return lc;
     }
 
     line = line_id;
     if (line_id == -1) {
-	line = display->selected->value[0];
+	line = display->selected.values->value[0];
     }
 
     if (!Vect_line_alive(display->mapInfo, line)) {
@@ -222,13 +222,13 @@
 	return -1;
     }
 
-    if (line_id == -1 && display->selected->n_values < 1) {
+    if (line_id == -1 && display->selected.values->n_values < 1) {
 	return -1;
     }
     
     line = -1;
     if (line_id == -1) {
-	line = display->selected->value[0];
+	line = display->selected.values->value[0];
     }
      
     if (!Vect_line_alive(display->mapInfo, line)) {
@@ -257,7 +257,7 @@
     }
 
     /* register changeset */
-    AddActionToChangeset(changesets.size(), REWRITE, display->selected->value[0]);
+    AddActionToChangeset(changesets.size(), REWRITE, display->selected.values->value[0]);
 
     ret = Vect_rewrite_line(display->mapInfo, line, type,
 			    Points, Cats);
@@ -272,7 +272,7 @@
 
     if (line_id == -1) {
 	/* update line id since the line was rewritten */
-	display->selected->value[0] = ret;
+	display->selected.values->value[0] = ret;
     }
 
     Vect_destroy_line_struct(Points);

Modified: grass/branches/develbranch_6/gui/wxpython/vdigit/driver.cpp
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/vdigit/driver.cpp	2008-08-20 14:02:24 UTC (rev 32925)
+++ grass/branches/develbranch_6/gui/wxpython/vdigit/driver.cpp	2008-08-20 18:03:58 UTC (rev 32926)
@@ -41,8 +41,8 @@
     pointsScreen = new wxList();
     cats = Vect_new_cats_struct();
     
-    selected = Vect_new_list();
-    selectedDupl = Vect_new_list();
+    selected.values = Vect_new_list();
+    selected.valuesDupl = Vect_new_list();
 
     drawSegments = false;
 
@@ -68,8 +68,8 @@
     Vect_destroy_line_struct(points);
     delete pointsScreen;
     Vect_destroy_cats_struct(cats);
-    Vect_destroy_list(selected);
-    Vect_destroy_list(selectedDupl);
+    Vect_destroy_list(selected.values);
+    Vect_destroy_list(selected.valuesDupl);
 }
 
 /**
@@ -913,8 +913,8 @@
 
     std::cerr << "selected: ";
 
-    for (int i = 0; i < selected->n_values; i++) {
-	std::cerr << selected->value[i] << " ";
+    for (int i = 0; i < selected.values->n_values; i++) {
+	std::cerr << selected.values->value[i] << " ";
     }
     std::cerr << std::endl;
 
@@ -951,6 +951,8 @@
     drawSegments = false;
     drawSelected = true;
 
+    selected.isId = true;
+
     list = Vect_new_list();
     bbox = Vect_new_line_struct();
 
@@ -982,10 +984,10 @@
 	}
 	
 	if (!IsSelected(line)) {
-	    Vect_list_append(selected, line);
+	    Vect_list_append(selected.values, line);
 	}
 	else {
-	    Vect_list_delete(selected, line);
+	    Vect_list_delete(selected.values, line);
 	}
     }
 
@@ -1018,15 +1020,17 @@
 
     drawSelected = true;
 
+    selected.isId = true;
+
     line = Vect_find_line(mapInfo, x, y, z,
 			  type, thresh, with_z, 0);
 
     if (line > 0) {
 	if (!IsSelected(line)) {
-	    Vect_list_append(selected, line);
+	    Vect_list_append(selected.values, line);
 	}
 	else {
-	    Vect_list_delete(selected, line);
+	    Vect_list_delete(selected.values, line);
 	}
 
 	type = Vect_read_line (mapInfo, points, cats, line);
@@ -1055,9 +1059,18 @@
 */
 bool DisplayDriver::IsSelected(int line)
 {
-    if (Vect_val_in_list(selected, line))
-	return true;
-
+    if (selected.isId) {
+	if (Vect_val_in_list(selected.values, line))
+	    return true;
+    }
+    else {
+	for (int i = 0; i < cats->n_cats; i++) {
+	    if (cats->field[i] == 1 &&
+		Vect_val_in_list(selected.values, cats->cat[i])) 
+		return true;
+	}
+    }
+    
     return false;
 }
 
@@ -1072,7 +1085,7 @@
 std::vector<int> DisplayDriver::GetSelected(bool grassId)
 {
     if (grassId)
-	return ListToVector(selected);
+	return ListToVector(selected.values);
 
     std::vector<int> dc_ids;
 
@@ -1081,7 +1094,7 @@
     }
     else {
 	int npoints;
-	Vect_read_line(mapInfo, points, NULL, selected->value[0]);
+	Vect_read_line(mapInfo, points, NULL, selected.values->value[0]);
 	npoints = points->n_points;
 	for (int i = 1; i < 2 * npoints; i++) {
 	  dc_ids.push_back(i);
@@ -1107,29 +1120,29 @@
     APoints = Vect_new_line_struct();
     BPoints = Vect_new_line_struct();
 
-    Vect_reset_list(selectedDupl);
+    Vect_reset_list(selected.valuesDupl);
 
-    for (int i = 0; i < selected->n_values; i++) {
-	line = selected->value[i];
+    for (int i = 0; i < selected.values->n_values; i++) {
+	line = selected.values->value[i];
 	if (IsDuplicated(line))
 	    continue;
 	
 	Vect_read_line(mapInfo, APoints, NULL, line);
 	
-	for (int j = 0; j < selected->n_values; j++) {
-	    if (i == j || IsDuplicated(selected->value[j]))
+	for (int j = 0; j < selected.values->n_values; j++) {
+	    if (i == j || IsDuplicated(selected.values->value[j]))
 		continue;
 	    
-	    Vect_read_line(mapInfo, BPoints, NULL, selected->value[j]);
+	    Vect_read_line(mapInfo, BPoints, NULL, selected.values->value[j]);
 	    
 	    if (Vect_line_check_duplicate (APoints, BPoints, WITHOUT_Z)) {
 		if (ids.find(i) == ids.end()) {
 		    ids[i] = std::vector<int> ();
-		    ids[i].push_back(selected->value[i]);
-		    Vect_list_append(selectedDupl, selected->value[i]);
+		    ids[i].push_back(selected.values->value[i]);
+		    Vect_list_append(selected.valuesDupl, selected.values->value[i]);
 		}
-		ids[i].push_back(selected->value[j]);
-		Vect_list_append(selectedDupl, selected->value[j]);
+		ids[i].push_back(selected.values->value[j]);
+		Vect_list_append(selected.valuesDupl, selected.values->value[j]);
 	    }
 	}
     }
@@ -1150,7 +1163,7 @@
 */
 bool DisplayDriver::IsDuplicated(int line)
 {
-    if (Vect_val_in_list(selectedDupl, line))
+    if (Vect_val_in_list(selected.valuesDupl, line))
 	return true;
     
     return false;
@@ -1160,16 +1173,19 @@
    \brief Set selected vector objects
    
    \param[in] list of GRASS ids to be set
+   \param[in] cat if True expect categories instead of feature ids
 
    \return 1
 */
-int DisplayDriver::SetSelected(std::vector<int> id)
+int DisplayDriver::SetSelected(std::vector<int> id, bool cat)
 {
     drawSelected = true;
 
-    VectorToList(selected, id);
+    VectorToList(selected.values, id);
+    
+    selected.isId = !cat;
 
-    if (selected->n_values <= 0)
+    if (selected.values->n_values <= 0)
 	drawSegments = false;
 
     return 1;
@@ -1191,7 +1207,7 @@
     for (std::vector<int>::const_iterator i = id.begin(), e = id.end();
 	 i != e; ++i) {
 	if (IsSelected(*i)) {
-	    Vect_list_delete(selected, *i);
+	    Vect_list_delete(selected.values, *i);
 	}
 	if (settings.highlightDupl.enabled && IsDuplicated(*i)) {
 	    checkForDupl = true;
@@ -1202,7 +1218,7 @@
 	GetDuplicates();
     }
 
-    return selected->n_values;
+    return selected.values->n_values;
 }
 
 /**
@@ -1230,11 +1246,11 @@
     std::vector<int> returnId;
 
     // only one object can be selected
-    if (selected->n_values != 1 || !drawSegments) 
+    if (selected.values->n_values != 1 || !drawSegments) 
 	return returnId;
 
     startId = 1;
-    line = selected->value[0];
+    line = selected.values->value[0];
 
     type = Vect_read_line (mapInfo, points, cats, line);
 
@@ -1525,3 +1541,76 @@
 
     return 1;
 }
+
+/*!
+  \brief Get minimal region extent of selected features
+
+  \return n,s,w,e
+*/
+std::vector<int> DisplayDriver::GetRegionSelected()
+{
+    std::vector<int> region;
+
+    BOUND_BOX region_box, line_box;
+    struct ilist *list, *list_tmp;
+
+    list = list_tmp = NULL;
+
+    G_zero(&region_box, sizeof(region_box));
+    
+    if (!selected.isId) { /* -> cats */
+	list = Vect_new_list();
+	list_tmp = Vect_new_list();
+	/* can't use here
+	 *
+	  Vect_cidx_find_all(mapInfo, 1, GV_POINTS | GV_LINES,
+	  selected.values->value[i],
+	  list_tmp);
+	*/
+	int type;
+	bool found;
+	for (int line = 1; line < Vect_get_num_lines(mapInfo); line++) {
+	    type = Vect_read_line (mapInfo, NULL, cats, line);
+	    if (!(type & (GV_POINTS | GV_LINES)))
+		continue;
+	    
+	    found = false;
+	    for (int i = 0; i < cats->n_cats && !found; i++) {
+		for (int j = 0; j < selected.values->n_values && !found; j++) {
+		    if (cats->cat[i] == selected.values->value[j])
+			found = true;
+		}
+	    }
+	    if (found)
+		Vect_list_append(list, line);
+	}
+    }
+    else {
+	list = selected.values;
+    }
+    
+    for (int i = 0; i < list->n_values; i++) {
+	if (!Vect_get_line_box(mapInfo, list->value[i], &line_box))
+	    continue;
+
+	if (i == 0) {
+	    Vect_box_copy(&region_box, &line_box);
+	}
+	else {
+	    Vect_box_extend(&region_box, &line_box);
+	}
+    }
+
+    if (list && list != selected.values) {
+	Vect_destroy_list(list);
+    }
+    if (list_tmp)
+	Vect_destroy_list(list_tmp);
+	
+    region.push_back(region_box.N);
+    region.push_back(region_box.S);
+    region.push_back(region_box.W);
+    region.push_back(region_box.E);
+
+    return region;
+}

Modified: grass/branches/develbranch_6/gui/wxpython/vdigit/driver.h
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/vdigit/driver.h	2008-08-20 14:02:24 UTC (rev 32925)
+++ grass/branches/develbranch_6/gui/wxpython/vdigit/driver.h	2008-08-20 18:03:58 UTC (rev 32926)
@@ -55,8 +55,13 @@
     ids_map ids; // gId : {dcIds, ...}
     */
 
-    struct ilist *selected;
-    struct ilist *selectedDupl;
+    struct _selected {
+	struct ilist *values;
+	struct ilist *valuesDupl;
+	
+	bool isId; /* id or cat ? */
+    } selected;
+    
     bool drawSelected;
 
     bool drawSegments;         // draw segments of selected line
@@ -178,7 +183,8 @@
 
     std::vector<int> GetSelected(bool);
     std::map<int, std::vector <int> > GetDuplicates();
-    int SetSelected(std::vector<int>);
+    std::vector<int> GetRegionSelected();
+    int SetSelected(std::vector<int>, bool);
     int UnSelect(std::vector<int>);
     std::vector<int> GetSelectedVertex(double, double, double);
     void DrawSelected(bool);

Modified: grass/branches/develbranch_6/gui/wxpython/vdigit/line.cpp
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/vdigit/line.cpp	2008-08-20 14:02:24 UTC (rev 32925)
+++ grass/branches/develbranch_6/gui/wxpython/vdigit/line.cpp	2008-08-20 18:03:58 UTC (rev 32926)
@@ -310,11 +310,11 @@
 
     /* register changeset */
     changeset = changesets.size();
-    for (int i = 0; i < display->selected->n_values; i++) {
-	AddActionToChangeset(changeset, DELETE, display->selected->value[i]);
+    for (int i = 0; i < display->selected.values->n_values; i++) {
+	AddActionToChangeset(changeset, DELETE, display->selected.values->value[i]);
     }
 
-    ret = Vedit_split_lines(display->mapInfo, display->selected,
+    ret = Vedit_split_lines(display->mapInfo, display->selected.values,
 			    point, thresh, list);
 
     for (int i = 0; i < list->n_values; i++) {
@@ -356,8 +356,8 @@
 	Cats = Vect_new_cats_struct();
 	// List = Vect_new_list();
 	Cats_del = Vect_new_cats_struct();
-	for (int i = 0; i < display->selected->n_values; i++) {
-	    if (Vect_read_line(display->mapInfo, NULL, Cats, display->selected->value[i]) < 0) {
+	for (int i = 0; i < display->selected.values->n_values; i++) {
+	    if (Vect_read_line(display->mapInfo, NULL, Cats, display->selected.values->value[i]) < 0) {
 		Vect_destroy_cats_struct(Cats_del);
 		//Vect_destroy_list(List);
 		return -1;
@@ -387,11 +387,11 @@
 
     /* register changeset */
     changeset = changesets.size();
-    for (int i = 0; i < display->selected->n_values; i++) {
-	AddActionToChangeset(changeset, DELETE, display->selected->value[i]);
+    for (int i = 0; i < display->selected.values->n_values; i++) {
+	AddActionToChangeset(changeset, DELETE, display->selected.values->value[i]);
     }
 
-    ret = Vedit_delete_lines(display->mapInfo, display->selected);
+    ret = Vedit_delete_lines(display->mapInfo, display->selected.values);
 
     if (ret > 0 && delete_records) {
 	struct field_info *fi;
@@ -497,18 +497,18 @@
 
     /* register changeset */
     changeset = changesets.size();
-    for (int i = 0; i < display->selected->n_values; i++) {
-	AddActionToChangeset(changeset, REWRITE, display->selected->value[i]);
+    for (int i = 0; i < display->selected.values->n_values; i++) {
+	AddActionToChangeset(changeset, REWRITE, display->selected.values->value[i]);
     }
     nlines = Vect_get_num_lines(display->mapInfo);
 
     ret = Vedit_move_lines(display->mapInfo, BgMap, nbgmaps,
-			   display->selected,
+			   display->selected.values,
 			   move_x, move_y, move_z,
 			   snap, thresh);
 
     if (ret > 0) {
-	for (int i = 0; i < display->selected->n_values; i++) {
+	for (int i = 0; i < display->selected.values->n_values; i++) {
 	    changesets[changeset][i].line = nlines + i + 1;
 	}
     }
@@ -540,15 +540,15 @@
 
     /* register changeset */
     changeset = changesets.size();
-    for (int i = 0; i < display->selected->n_values; i++) {
-	AddActionToChangeset(changeset, REWRITE, display->selected->value[i]);
+    for (int i = 0; i < display->selected.values->n_values; i++) {
+	AddActionToChangeset(changeset, REWRITE, display->selected.values->value[i]);
     }
     nlines = Vect_get_num_lines(display->mapInfo);
 
-    ret = Vedit_flip_lines(display->mapInfo, display->selected);
+    ret = Vedit_flip_lines(display->mapInfo, display->selected.values);
 
     if (ret > 0) {
-	for (int i = 0; i < display->selected->n_values; i++) {
+	for (int i = 0; i < display->selected.values->n_values; i++) {
 	    changesets[changeset][i].line = nlines + i + 1;
 	}
     }
@@ -575,16 +575,16 @@
 
     /* register changeset */
     changeset = changesets.size();
-    for (int i = 0; i < display->selected->n_values; i++) {
-	AddActionToChangeset(changeset, DELETE, display->selected->value[i]);
+    for (int i = 0; i < display->selected.values->n_values; i++) {
+	AddActionToChangeset(changeset, DELETE, display->selected.values->value[i]);
     }
 
-    ret = Vedit_merge_lines(display->mapInfo, display->selected);
+    ret = Vedit_merge_lines(display->mapInfo, display->selected.values);
 
     if (ret > 0) {
 	/* update changeset */
-	for (int i = 0; i < display->selected->n_values; i++) {
-	    line = display->selected->value[i];
+	for (int i = 0; i < display->selected.values->n_values; i++) {
+	    line = display->selected.values->value[i];
 	    if (Vect_line_alive(display->mapInfo, line)) {
 		RemoveActionFromChangeset(changeset, DELETE, line);
 	    }
@@ -593,7 +593,7 @@
 	    line = Vect_get_updated_line(display->mapInfo, i);
 	    AddActionToChangeset(changeset, ADD, line);
 	}
-	for (int i = 0; i < display->selected->n_values; i++) {
+	for (int i = 0; i < display->selected.values->n_values; i++) {
 	}
     }
     else {
@@ -621,17 +621,17 @@
 
     /* register changeset */
     changeset = changesets.size();
-    for (int i = 0; i < display->selected->n_values; i++) {
-	AddActionToChangeset(changeset, DELETE, display->selected->value[i]);
+    for (int i = 0; i < display->selected.values->n_values; i++) {
+	AddActionToChangeset(changeset, DELETE, display->selected.values->value[i]);
     }
 
-    ret = Vect_break_lines_list(display->mapInfo, display->selected, NULL,
+    ret = Vect_break_lines_list(display->mapInfo, display->selected.values, NULL,
 				GV_LINES, NULL, NULL);
 
     if (ret > 0) {
 	/* update changeset */
-	for (int i = 0; i < display->selected->n_values; i++) {
-	    line = display->selected->value[i];
+	for (int i = 0; i < display->selected.values->n_values; i++) {
+	    line = display->selected.values->value[i];
 	    if (Vect_line_alive(display->mapInfo, line)) {
 		RemoveActionFromChangeset(changeset, DELETE, line);
 	    }
@@ -640,7 +640,7 @@
 	    line = Vect_get_updated_line(display->mapInfo, i);
 	    AddActionToChangeset(changeset, ADD, line);
 	}
-	for (int i = 0; i < display->selected->n_values; i++) {
+	for (int i = 0; i < display->selected.values->n_values; i++) {
 	}
     }
     else {
@@ -666,7 +666,7 @@
 	return -1;
     }
 
-    Vect_snap_lines_list (display->mapInfo, display->selected,
+    Vect_snap_lines_list (display->mapInfo, display->selected.values,
 			  thresh, NULL, NULL);
 
     return 0;
@@ -689,13 +689,13 @@
 
     /* register changeset */
     changeset = changesets.size();
-    for (int i = 0; i < display->selected->n_values; i++) {
-	AddActionToChangeset(changeset, DELETE, display->selected->value[i]);
+    for (int i = 0; i < display->selected.values->n_values; i++) {
+	AddActionToChangeset(changeset, DELETE, display->selected.values->value[i]);
     }
 
     nlines_diff = Vect_get_num_lines(display->mapInfo);
 
-    ret = Vedit_connect_lines(display->mapInfo, display->selected,
+    ret = Vedit_connect_lines(display->mapInfo, display->selected.values,
 			      thresh);
 
     if (ret > 0) {
@@ -734,7 +734,7 @@
 	return -1;
     }
 
-    ret = Vedit_bulk_labeling (display->mapInfo, display->selected,
+    ret = Vedit_bulk_labeling (display->mapInfo, display->selected.values,
 			       x1, y1, x2, y2, start, step);
 
     return ret;
@@ -778,7 +778,7 @@
 	}
     }
     else {
-	list = display->selected;
+	list = display->selected.values;
     }
 
     nlines = Vect_get_num_lines(display->mapInfo);
@@ -794,7 +794,7 @@
 	}
     }
 
-    if (list != display->selected) {
+    if (list != display->selected.values) {
 	Vect_destroy_list(list);
     }
 
@@ -878,13 +878,13 @@
 
     /* register changeset */
     changeset = changesets.size();
-    for (int i = 0; i < display->selected->n_values; i++) {
-	AddActionToChangeset(changeset, DELETE, display->selected->value[i]);
+    for (int i = 0; i < display->selected.values->n_values; i++) {
+	AddActionToChangeset(changeset, DELETE, display->selected.values->value[i]);
     }
 
     nlines_diff = Vect_get_num_lines(display->mapInfo);
 
-    ret = Vedit_chtype_lines (display->mapInfo, display->selected,
+    ret = Vedit_chtype_lines (display->mapInfo, display->selected.values,
 			       &npoints, &ncentroids,
 			       &nlines, &nboundaries);
 

Modified: grass/branches/develbranch_6/gui/wxpython/vdigit/vertex.cpp
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/vdigit/vertex.cpp	2008-08-20 14:02:24 UTC (rev 32925)
+++ grass/branches/develbranch_6/gui/wxpython/vdigit/vertex.cpp	2008-08-20 18:03:58 UTC (rev 32926)
@@ -47,7 +47,7 @@
     if (!display->mapInfo)
 	return -1;
 
-    if (display->selected->n_values != 1)
+    if (display->selected.values->n_values != 1)
 	return 0;
 
     BgMap = NULL;
@@ -66,11 +66,11 @@
     Vect_append_point(point, x, y, z);
 
     /* register changeset */
-    AddActionToChangeset(changesets.size(), REWRITE, display->selected->value[0]);
+    AddActionToChangeset(changesets.size(), REWRITE, display->selected.values->value[0]);
 
     /* move only first found vertex in bbox */
     ret = Vedit_move_vertex(display->mapInfo, BgMap, nbgmaps, 
-			    display->selected,
+			    display->selected.values,
 			    point, thresh_coords, thresh_snap,
 			    move_x, move_y, move_z,
 			    1, snap); 
@@ -114,21 +114,21 @@
     if (!display->mapInfo)
 	return -1;
 
-    if (display->selected->n_values != 1)
+    if (display->selected.values->n_values != 1)
 	return 0;
 
     point = Vect_new_line_struct();
     Vect_append_point(point, x, y, z);
 
     /* register changeset */
-    AddActionToChangeset(changesets.size(), REWRITE, display->selected->value[0]);
+    AddActionToChangeset(changesets.size(), REWRITE, display->selected.values->value[0]);
 
     if (add) {
-	ret = Vedit_add_vertex(display->mapInfo, display->selected,
+	ret = Vedit_add_vertex(display->mapInfo, display->selected.values,
 			       point, thresh);
     }
     else {
-	ret = Vedit_remove_vertex(display->mapInfo, display->selected,
+	ret = Vedit_remove_vertex(display->mapInfo, display->selected.values,
 				  point, thresh);
     }
 



More information about the grass-commit mailing list