[GRASS-SVN] r29940 - in grass/trunk/gui/wxpython: gui_modules vdigit

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Feb 3 17:23:27 EST 2008


Author: martinl
Date: 2008-02-03 17:23:27 -0500 (Sun, 03 Feb 2008)
New Revision: 29940

Modified:
   grass/trunk/gui/wxpython/gui_modules/digit.py
   grass/trunk/gui/wxpython/gui_modules/toolbars.py
   grass/trunk/gui/wxpython/gui_modules/wxgui_utils.py
   grass/trunk/gui/wxpython/vdigit/cats.cpp
   grass/trunk/gui/wxpython/vdigit/digit.h
   grass/trunk/gui/wxpython/vdigit/driver.cpp
   grass/trunk/gui/wxpython/vdigit/line.cpp
Log:
wxGUI/vdigit: Various improvements/fixes in vdigit/vedit interface.
Settings dialog improved.


Modified: grass/trunk/gui/wxpython/gui_modules/digit.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/digit.py	2008-02-03 20:22:15 UTC (rev 29939)
+++ grass/trunk/gui/wxpython/gui_modules/digit.py	2008-02-03 22:23:27 UTC (rev 29940)
@@ -141,14 +141,15 @@
             if USEVEDIT:
                 categoryCmd = gcmd.Command(cmd=["v.category", "-g", "--q",
                                                 "input=%s" % self.map, 
-                                                "option=report",
-                                                "layer=%d" % self.settings["layer"]])
+                                                "option=report"])
 
                 if categoryCmd.returncode != 0:
                     return False
         
                 for line in categoryCmd.ReadStdOutput():
                     if "all" in line:
+                        if self.settings['layer'] != int(line.split(' ')[0]):
+                            continue
                         try:
                             maxCat = int(line.split(' ')[-1]) + 1
                             self.settings['category'] = maxCat
@@ -161,12 +162,9 @@
     def SetCategory(self):
         """Return category number to use (according Settings)"""
         if self.settings["categoryMode"] == "No category":
-            self.settings["category"] = "None"
+            self.settings["category"] = 1
         elif self.settings["categoryMode"] == "Next to use":
             self.SetCategoryNextToUse()
-        else:
-            if self.settings["category"] == "None":
-                self.SetCategoryNextToUse()
 
         return self.settings["category"]
 
@@ -746,6 +744,21 @@
         
         return ids
 
+    def GetLayers(self):
+        """Return list of layers"""
+        layerCommand = gcmd.Command(cmd=["v.db.connect",
+                                             "-g", "--q",
+                                             "map=%s" % self.map],
+                                        rerr=None, stderr=None)
+        if layerCommand.returncode == 0:
+            layers = []
+            for line in layerCommand.ReadStdOutput():
+                lineList = line.split(' ')
+                layers.append(int(lineList[0]))
+            return layers
+
+        return [1]
+
 class VDigit(AbstractDigit):
     """
     Prototype of digitization class based on v.digit reimplementation
@@ -975,7 +988,11 @@
     def GetLineCats(self):
         """Get layer/category pairs from given (selected) line"""
         return self.digit.GetLineCats()
-        
+
+    def GetLayers(self):
+        """Get list of layers"""
+        return self.digit.GetLayers()
+
     def __getSnapThreshold(self):
         """Get snap mode and threshold value
 
@@ -1393,10 +1410,9 @@
         self.lineWidthValue = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(50, -1),
                                           initial=self.parent.digit.settings["lineWidth"][0],
                                           min=1, max=1e6)
-        self.lineWidthUnit = wx.ComboBox(parent=panel, id=wx.ID_ANY, size=(125, -1),
-                                         style=wx.CB_SIMPLE | wx.CB_READONLY,
-                                         choices=["screen pixels", "map units"])
-        self.lineWidthUnit.SetValue(self.parent.digit.settings["lineWidth"][1])
+        self.lineWidthUnit = wx.Choice(parent=panel, id=wx.ID_ANY, size=(125, -1),
+                                       choices=["screen pixels", "map units"])
+        self.lineWidthUnit.SetStringSelection(self.parent.digit.settings["lineWidth"][1])
         flexSizer.Add(text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
         flexSizer.Add(self.lineWidthValue, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
         flexSizer.Add(self.lineWidthUnit, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
@@ -1419,11 +1435,10 @@
                                          initial=self.parent.digit.settings["snapping"][0],
                                          min=1, max=1e6)
         self.snappingValue.Bind(wx.EVT_SPINCTRL, self.OnChangeSnappingValue)
-        self.snappingUnit = wx.ComboBox(parent=panel, id=wx.ID_ANY, size=(125, -1),
-                                        style=wx.CB_SIMPLE | wx.CB_READONLY,
-                                        choices=["screen pixels", "map units"])
-        self.snappingUnit.SetValue(self.parent.digit.settings["snapping"][1])
-        self.snappingUnit.Bind(wx.EVT_COMBOBOX, self.OnChangeSnappingUnits)
+        self.snappingUnit = wx.Choice(parent=panel, id=wx.ID_ANY, size=(125, -1),
+                                      choices=["screen pixels", "map units"])
+        self.snappingUnit.SetStringSelection(self.parent.digit.settings["snapping"][1])
+        self.snappingUnit.Bind(wx.EVT_CHOICE, self.OnChangeSnappingUnits)
         flexSizer1.Add(text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
         flexSizer1.Add(self.snappingValue, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
         flexSizer1.Add(self.snappingUnit, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
@@ -1444,7 +1459,7 @@
         vertexSizer.Add(item=self.snapVertex, proportion=0, flag=wx.EXPAND)
         self.mapUnits = self.parent.MapWindow.Map.ProjInfo()['units']
         self.snappingInfo = wx.StaticText(parent=panel, id=wx.ID_ANY,
-                                          label=_("Snapping threshold is currently %.1f %s") % \
+                                          label=_("Snapping threshold is %.1f %s") % \
                                               (self.parent.digit.driver.GetThreshold(),
                                                self.mapUnits))
         vertexSizer.Add(item=self.snappingInfo, proportion=0,
@@ -1471,27 +1486,31 @@
         settings = ((_("Layer"), 1), (_("Category"), 1), (_("Mode"), _("Next to use")))
         # layer
         text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Layer"))
-        self.layer = wx.TextCtrl(parent=panel, id=wx.ID_ANY, size=(125, -1),
-                                 value=str(self.parent.digit.settings["layer"])) # TODO: validator
+        if self.parent.digit.map:
+            layers = map(str, self.parent.digit.GetLayers())
+        else:
+            layers = [str(self.parent.digit.settings["layer"])]
+        self.layer = wx.Choice(parent=panel, id=wx.ID_ANY, size=(125, -1),
+                               choices=layers)
+        self.layer.SetStringSelection(str(self.parent.digit.settings["layer"]))
         flexSizer.Add(item=text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
         flexSizer.Add(item=self.layer, proportion=0,
                       flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
         # category number
         text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Category number"))
-        self.category = wx.TextCtrl(parent=panel, id=wx.ID_ANY, size=(125, -1),
-                                    value=str(self.parent.digit.settings["category"])) # TODO: validator
+        self.category = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(125, -1),
+                                    initial=self.parent.digit.settings["category"],
+                                    min=-1e9, max=1e9) 
         if self.parent.digit.settings["categoryMode"] != "Manual entry":
-            self.category.SetEditable(False)
             self.category.Enable(False)
         flexSizer.Add(item=text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
         flexSizer.Add(item=self.category, proportion=0,
                       flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
         # category mode
         text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Category mode"))
-        self.categoryMode = wx.ComboBox(parent=panel, id=wx.ID_ANY,
-                                        style=wx.CB_SIMPLE | wx.CB_READONLY, size=(125, -1),
-                                        choices=[_("Next to use"), _("Manual entry"), _("No category")])
-        self.categoryMode.SetValue(self.parent.digit.settings["categoryMode"])
+        self.categoryMode = wx.Choice(parent=panel, id=wx.ID_ANY, size=(125, -1),
+                                      choices=[_("Next to use"), _("Manual entry"), _("No category")])
+        self.categoryMode.SetStringSelection(self.parent.digit.settings["categoryMode"])
         flexSizer.Add(item=text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
         flexSizer.Add(item=self.categoryMode, proportion=0,
                       flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
@@ -1512,7 +1531,8 @@
 
         # bindings
         self.Bind(wx.EVT_CHECKBOX, self.OnChangeAddRecord, self.addRecord)
-        self.Bind(wx.EVT_COMBOBOX, self.OnChangeCategoryMode, self.categoryMode)
+        self.Bind(wx.EVT_CHOICE, self.OnChangeCategoryMode, self.categoryMode)
+        self.Bind(wx.EVT_CHOICE, self.OnChangeLayer, self.layer)
 
         panel.SetSizer(border)
         
@@ -1647,16 +1667,24 @@
         self.parent.digit.settings["categoryMode"] = mode
         if mode == "Manual entry": # enable
             self.category.Enable(True)
-            self.category.SetEditable(True)
         elif self.category.IsEnabled(): # disable
-            self.category.SetEditable(False)
             self.category.Enable(False)
 
         if mode == "No category" and self.addRecord.IsChecked():
             self.addRecord.SetValue(False)
         self.parent.digit.SetCategory()
-        self.category.SetValue(str(self.parent.digit.settings['category']))
+        self.category.SetValue(self.parent.digit.settings['category'])
 
+    def OnChangeLayer(self, event):
+        """Layer changed"""
+        layer = int(event.GetString())
+        if layer > 0:
+            self.parent.digit.settings['layer'] = layer
+            self.parent.digit.SetCategory()
+            self.category.SetValue(self.parent.digit.settings['category'])
+            
+        event.Skip()
+
     def OnChangeAddRecord(self, event):
         """Checkbox 'Add new record' status changed"""
         self.category.SetValue(str(self.parent.digit.SetCategory()))
@@ -1664,17 +1692,21 @@
     def OnChangeSnappingValue(self, event):
         """Change snapping value - update static text"""
         value = self.snappingValue.GetValue()
-        threshold = self.parent.digit.driver.GetThreshold(value)
-        self.snappingInfo.SetLabel(_("Snapping threshold is currently %.1f %s") % \
-                                       (threshold,
-                                        self.mapUnits))
+        if self.snappingUnit.GetStringSelection() == "map units":
+            threshold = value
+        else:
+            threshold = self.parent.digit.driver.GetThreshold(value)
 
+        self.snappingInfo.SetLabel(_("Snapping threshold is %.1f %s") % 
+                                   (threshold,
+                                    self.mapUnits))
+
         event.Skip()
 
     def OnChangeSnappingUnits(self, event):
         """Snapping units change -> update static text"""
         value = self.snappingValue.GetValue()
-        units = self.snappingUnit.GetValue()
+        units = self.snappingUnit.GetStringSelection()
         threshold = self.parent.digit.driver.GetThreshold(value, units)
 
         if units == "map units":
@@ -1735,21 +1767,21 @@
                 self.parent.digit.settings[key] = (None, color.GetColour())
         # display
         self.parent.digit.settings["lineWidth"] = (int(self.lineWidthValue.GetValue()),
-                                                   self.lineWidthUnit.GetValue())
+                                                   self.lineWidthUnit.GetStringSelection())
 
         # snapping
         self.parent.digit.settings["snapping"] = (int(self.snappingValue.GetValue()), # value
-                                      self.snappingUnit.GetValue()) # unit
+                                      self.snappingUnit.GetStringSelection()) # unit
         self.parent.digit.settings["snapToVertex"] = self.snapVertex.IsChecked()
         
         # digitize new feature
         self.parent.digit.settings["addRecord"] = self.addRecord.IsChecked()
-        self.parent.digit.settings["layer"] = int(self.layer.GetValue())
+        self.parent.digit.settings["layer"] = int(self.layer.GetStringSelection())
         if self.parent.digit.settings["categoryMode"] == "No category":
             self.parent.digit.settings["category"] = None
         else:
             self.parent.digit.settings["category"] = int(self.category.GetValue())
-        self.parent.digit.settings["categoryMode"] = self.categoryMode.GetValue()
+        self.parent.digit.settings["categoryMode"] = self.categoryMode.GetStringSelection()
 
         # delete existing feature
         self.parent.digit.settings["delRecord"] = self.deleteRecord.IsChecked()

Modified: grass/trunk/gui/wxpython/gui_modules/toolbars.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/toolbars.py	2008-02-03 20:22:15 UTC (rev 29939)
+++ grass/trunk/gui/wxpython/gui_modules/toolbars.py	2008-02-03 22:23:27 UTC (rev 29940)
@@ -364,7 +364,7 @@
         self.type   = "centroid"
         self.parent.MapWindow.mouse['box'] = 'point'
 
-    def OnExit (self, event):
+    def OnExit (self, event=None):
         """Quit digitization tool"""
         # stop editing of the currently selected map layer
         try:

Modified: grass/trunk/gui/wxpython/gui_modules/wxgui_utils.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/wxgui_utils.py	2008-02-03 20:22:15 UTC (rev 29939)
+++ grass/trunk/gui/wxpython/gui_modules/wxgui_utils.py	2008-02-03 22:23:27 UTC (rev 29940)
@@ -361,14 +361,7 @@
             event.Skip()
             return
 
-        # mark layer as 'edited'
-        self.mapdisplay.digittoolbar.StopEditing(maplayer)
-
-        if self.mapdisplay.digittoolbar: # disable the tool
-            self.mapdisplay.RemoveToolbar("digit")
-        else: # tool already enabled
-            pass
-
+        self.mapdisplay.digittoolbar.OnExit()
         self.mapdisplay.imgVectorMap = None
 
     def OnPopupProperties (self, event):

Modified: grass/trunk/gui/wxpython/vdigit/cats.cpp
===================================================================
--- grass/trunk/gui/wxpython/vdigit/cats.cpp	2008-02-03 20:22:15 UTC (rev 29939)
+++ grass/trunk/gui/wxpython/vdigit/cats.cpp	2008-02-03 22:23:27 UTC (rev 29940)
@@ -25,13 +25,11 @@
 */
 int Digit::InitCats()
 {
-    int nfields, field, index, ncats, max_cat;
+    int ndblinks, nfields, field, ncats, max_cat;
     int cat, type, id; 
 
-    struct lcat lc;
+    struct field_info *fi;
 
-    G_debug(2, "wxDigit.InitCats()");
-
     if (!cats.empty()) {	
 	cats.clear();
     }
@@ -40,22 +38,39 @@
 	return -1;
     }
 
+    /* initialization */
+    ndblinks = Vect_get_num_dblinks(display->mapInfo);
+    for (int i = 0; i < ndblinks; i++) {
+	fi = Vect_get_dblink(display->mapInfo, i);
+	if (fi) {
+	    cats[fi->number] = PORT_INT_MIN;
+	}
+    }
+
+    /* find max category */
     nfields = Vect_cidx_get_num_fields (display->mapInfo);
-    
+    G_debug(2, "wxDigit.InitCats(): nfields=%d", nfields);    
+
     for (int i = 0; i < nfields; i++ ) {
 	field = Vect_cidx_get_field_number(display->mapInfo, i);
-	ncats = Vect_cidx_get_num_cats_by_index(display->mapInfo, index);
+	ncats = Vect_cidx_get_num_cats_by_index(display->mapInfo, i);
 	for (int j = 0; j < ncats; j++) {
-	    Vect_cidx_get_cat_by_index (display->mapInfo, index, j, &cat, &type, &id);
-	    if (cat > max_cat)
-		max_cat = cat;
+	    Vect_cidx_get_cat_by_index (display->mapInfo, i, j, &cat, &type, &id);
+	    if (cat > cats[field])
+		cats[field] = cat;
 	}
 
-	lc.layer = Vect_cidx_get_field_number(display->mapInfo, i);
-	lc.cat = max_cat;
+	G_debug(3, "wxDigit.InitCats(): layer=%d, cat=%d", field, cats[field]);
+    }
 
-	cats.push_back(lc);
-	G_debug(3, "wxDigit.InitCats(): layer=%d, cat=%d", lc.layer, lc.cat);
+    /* set default values */
+    for(std::map<int, int>::const_iterator b = cats.begin(), e = cats.end();
+	b != e; ++b ) {
+	if (b->second == PORT_INT_MIN) {
+	    cats[b->first] = 0;
+	    G_debug(3, "wxDigit.InitCats(): layer=%d, cat=%d", b->first, cats[b->first]);
+	}
+
     }
 
     return 0;
@@ -71,12 +86,9 @@
 */
 int Digit::GetCategory(int layer)
 {
-    for(std::vector<struct lcat>::const_iterator i = cats.begin(), e = cats.end();
-	i != e; ++i) {
-	if (layer == (*i).layer) {
-	    G_debug(3, "v.digit.GetCategory(): layer=%d, cat=%d", (*i).layer, (*i).cat);
-	    return (*i).cat;
-	}
+    if (cats.find(layer) != cats.end()) {
+	G_debug(3, "v.digit.GetCategory(): layer=%d, cat=%d", layer, cats[layer]);
+	return cats[layer];
     }
 
     return -1;
@@ -89,37 +101,43 @@
    \param cats  category number to be set
 
    \return previosly set category
+   \return -1 if layer not available
 */
 int Digit::SetCategory(int layer, int cat)
 {
     int old_cat;
 
-    for(std::vector<struct lcat>::iterator i = cats.begin(), e = cats.end();
-	i != e; ++i) {
-	if (layer == (*i).layer) {
-	    old_cat = (*i).cat;
-	    (*i).cat = cat;
-	    G_debug(3, "wxDigit.SetCategory(): layer=%d, cat=%d", layer, cat);
-	}
+    if (cats.find(layer) != cats.end()) {
+	old_cat = cats[layer];
     }
+    else {
+	old_cat = -1;
+    }
 
+    cats[layer] = cat;
+    G_debug(3, "wxDigit.SetCategory(): layer=%d, cat=%d old_cat=%d",
+	    layer, cat, old_cat);
+
     return old_cat;
 }
 
 /**
-   \brief Copy categories from one vector feature to other
+   Get list of layers
 
-   \param cats  list of layer/category to be copied			       
-   \param ids   list of line ids where to copy categories
+   Requires InitCats() to be called.
 
-   \return number of modified features
-   \return -1 on error
+   \return list of layers
 */
-int Digit::CopyCats(std::vector<std::vector<int> > cats, std::vector<int> ids)
+std::vector<int> Digit::GetLayers()
 {
-  /* TODO */
+    std::vector<int> layers;
 
-  return 0;
+    for(std::map<int, int>::const_iterator b = cats.begin(), e = cats.end();
+	b != e; ++b ) {
+	layers.push_back(b->first);
+    }
+
+    return layers;
 }
 
 /**
@@ -170,3 +188,19 @@
 
     return lc;
 }
+
+/**
+   \brief Copy categories from one vector feature to other
+
+   \param cats  list of layer/category to be copied			       
+   \param ids   list of line ids where to copy categories
+
+   \return number of modified features
+   \return -1 on error
+*/
+int Digit::CopyCats(std::vector<std::vector<int> > cats, std::vector<int> ids)
+{
+  /* TODO */
+
+  return 0;
+}

Modified: grass/trunk/gui/wxpython/vdigit/digit.h
===================================================================
--- grass/trunk/gui/wxpython/vdigit/digit.h	2008-02-03 20:22:15 UTC (rev 29939)
+++ grass/trunk/gui/wxpython/vdigit/digit.h	2008-02-03 22:23:27 UTC (rev 29940)
@@ -8,11 +8,8 @@
 class Digit
 {
 private:
-    struct lcat {
-	int layer;
-	int cat;
-    };
-    std::vector<lcat> cats;
+    /* layer / max category */
+    std::map<int, int> cats;
 
     DisplayDriver *display;
 
@@ -54,7 +51,7 @@
     int CopyCats(std::vector<std::vector<int> >, std::vector<int>);
     int GetCategory(int);
     std::map<int, std::vector<int> > GetLineCats();
-
+    std::vector<int> GetLayers();
 };
 
 #endif /* __DIGIT_H__ */

Modified: grass/trunk/gui/wxpython/vdigit/driver.cpp
===================================================================
--- grass/trunk/gui/wxpython/vdigit/driver.cpp	2008-02-03 20:22:15 UTC (rev 29939)
+++ grass/trunk/gui/wxpython/vdigit/driver.cpp	2008-02-03 22:23:27 UTC (rev 29940)
@@ -44,7 +44,7 @@
     drawSegments = false;
 
     // avoid GUI crash when G_fatal_error() is called (opening the vector map)
-    Vect_set_fatal_error(GV_FATAL_PRINT);
+    // Vect_set_fatal_error(GV_FATAL_PRINT);
     // G_set_error_routine(print_error);
 }
 
@@ -439,9 +439,11 @@
     if (mapInfo) {
 	if (mapInfo->mode == GV_MODE_RW) {
 	    /* rebuild topology */
+	    Vect_build_partial(mapInfo, GV_BUILD_NONE, NULL);
 	    Vect_build(mapInfo, NULL);
 	}
-	ret = Vect_close(mapInfo);
+	/* close map and store topo/cidx */
+	ret = Vect_close(mapInfo); 
 	G_free ((void *) mapInfo);
 	mapInfo = NULL;
     }

Modified: grass/trunk/gui/wxpython/vdigit/line.cpp
===================================================================
--- grass/trunk/gui/wxpython/vdigit/line.cpp	2008-02-03 20:22:15 UTC (rev 29939)
+++ grass/trunk/gui/wxpython/vdigit/line.cpp	2008-02-03 22:23:27 UTC (rev 29940)
@@ -313,7 +313,7 @@
 		if (Cats_del->field[c] == fi->number) {
 		    sprintf (buf, " %s = %d", fi->key, Cats_del->cat[c]);
 		    db_append_string(&stmt, buf);
-		    if (n_cats > 0) {
+		    if (n_cats > 0 && c < Cats_del->n_cats) {
 			sprintf (buf, " or");
 			db_append_string(&stmt, buf);
 		    }



More information about the grass-commit mailing list