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

svn_grass at osgeo.org svn_grass at osgeo.org
Tue Jan 8 06:48:03 EST 2008


Author: martinl
Date: 2008-01-08 06:48:03 -0500 (Tue, 08 Jan 2008)
New Revision: 29601

Added:
   grass/trunk/gui/wxpython/vdigit/
   grass/trunk/gui/wxpython/vdigit/Makefile.in
   grass/trunk/gui/wxpython/vdigit/cats.cpp
   grass/trunk/gui/wxpython/vdigit/digit.cpp
   grass/trunk/gui/wxpython/vdigit/digit.h
   grass/trunk/gui/wxpython/vdigit/digit.i
   grass/trunk/gui/wxpython/vdigit/driver.cpp
   grass/trunk/gui/wxpython/vdigit/driver.h
   grass/trunk/gui/wxpython/vdigit/driver.i
   grass/trunk/gui/wxpython/vdigit/line.cpp
Removed:
   grass/trunk/gui/wxpython/display_driver/
   grass/trunk/gui/wxpython/vdigit/Makefile.in
   grass/trunk/gui/wxpython/vdigit/driver.cpp
   grass/trunk/gui/wxpython/vdigit/driver.h
   grass/trunk/gui/wxpython/vdigit/driver.i
Modified:
   grass/trunk/gui/wxpython/README
   grass/trunk/gui/wxpython/gui_modules/digit.py
   grass/trunk/gui/wxpython/gui_modules/mapdisp.py
Log:
wxGUI/vdigit: display_driver renamed to vdigit. Experimental interface for digitization initialized (currently v.edit is used on background which is slow for larger vector maps).


Modified: grass/trunk/gui/wxpython/README
===================================================================
--- grass/trunk/gui/wxpython/README	2008-01-08 11:30:08 UTC (rev 29600)
+++ grass/trunk/gui/wxpython/README	2008-01-08 11:48:03 UTC (rev 29601)
@@ -31,17 +31,10 @@
      http://www.activestate.com/store/download.aspx?prdGUID=b08b04e0-6872-4d9d-a722-7a0c2dea2758
 
  E.g. On Debian GNU/Linux install these packages:
- * libwxbase2.8-0
- * libwxbase2.8-dbg
- * libwxbase2.8-dev
- * libwxgtk2.8-0
- * libwxgtk2.8-dbg
- * libwxgtk2.8-dev
- * python-wxgtk2.8
- * wx2.8-doc
- * wx2.8-examples
- * wx2.8-headers
- * wx2.8-i18n
+ apt-get install libwxbase2.8-0 libwxbase2.8-dbg libwxbase2.8-dev \
+ 	 libwxgtk2.8-0 libwxgtk2.8-dbg libwxgtk2.8-dev \
+	 python-wxgtk2.8 wx2.8-doc wx2.8-examples \
+	 wx2.8-headers wx2.8-i18n
 
 1 - INSTALLATION
 

Modified: grass/trunk/gui/wxpython/gui_modules/digit.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/digit.py	2008-01-08 11:30:08 UTC (rev 29600)
+++ grass/trunk/gui/wxpython/gui_modules/digit.py	2008-01-08 11:48:03 UTC (rev 29601)
@@ -2,6 +2,7 @@
 MODULE: digit
 
 CLASSES:
+ * DigitError
  * AbstractDigit 
  * VEdit
  * VDigit
@@ -25,7 +26,7 @@
 AUTHORS: The GRASS Development Team
          Martin Landa <landa.martin gmail.com>
 
-COPYRIGHT: (C) 2007 by the GRASS Development Team
+COPYRIGHT: (C) 2007-2008 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.
@@ -45,21 +46,35 @@
 from debug import Debug as Debug
 import gselect 
 try:
-    driverPath = os.path.join(os.getenv("GISBASE"), "etc","wx", "display_driver")
-    sys.path.append(driverPath)
-    from grass6_wxdriver import DisplayDriver
+    digitPath = os.path.join(os.getenv("GISBASE"), "etc","wx", "vdigit")
+    sys.path.append(digitPath)
+    from grass6_wxvdigit import DisplayDriver
 except ImportError, err:
     print >> sys.stderr, "%sWARNING: Digitization tool is disabled (%s).%s" \
           "Detailed information in README file." % \
           (os.linesep, err, os.linesep)
 
 USEVEDIT = True
-    
+
+class DigitError(Exception):
+    def __init__(self, message):
+        self.message = message
+
+    def __str__(self):
+        wx.MessageBox(parent=None,
+                      message=self.message,
+                      style=wx.ICON_ERROR)
+
 class AbstractDigit:
     """
     Abstract digitization class
     """
     def __init__(self, mapwindow, settings=None):
+        """Initialization
+
+        @param mapwindow reference to mapwindow (MapFrame) instance
+        @param settings  initial settings of digitization tool
+        """
         self.map       = None
 
         Debug.msg (3, "AbstractDigit.__init__(): map=%s" % \
@@ -112,28 +127,31 @@
         """Find maximum category number in the map layer
         and update Digit.settings['category']
 
-        Returns 'True' on success, 'False' on failure
+        @return 'True' on success, 'False' on failure
         """
         # vector map layer without categories, reset to '1'
         self.settings['category'] = 1
 
         if self.map:
-            categoryCmd = gcmd.Command(cmd=["v.category", "-g", "--q",
-                                           "input=%s" % self.map, 
-                                           "option=report",
-                                           "layer=%d" % self.settings["layer"]])
+            if USEVEDIT:
+                categoryCmd = gcmd.Command(cmd=["v.category", "-g", "--q",
+                                                "input=%s" % self.map, 
+                                                "option=report",
+                                                "layer=%d" % self.settings["layer"]])
 
-            if categoryCmd.returncode != 0:
-                return False
+                if categoryCmd.returncode != 0:
+                    return False
         
-            for line in categoryCmd.ReadStdOutput():
-                if "all" in line:
-                    try:
-                        maxCat = int(line.split(' ')[-1]) + 1
-                        self.settings['category'] = maxCat
-                    except:
-                        return False
-                    return True
+                for line in categoryCmd.ReadStdOutput():
+                    if "all" in line:
+                        try:
+                            maxCat = int(line.split(' ')[-1]) + 1
+                            self.settings['category'] = maxCat
+                        except:
+                            return False
+                        return True
+            else:
+                self.settings['category'] = self.digit.GetCategory(self.settings['layer']) + 1
     
     def SetCategory(self):
         """Return category number to use (according Settings)"""
@@ -148,11 +166,16 @@
         return self.settings["category"]
 
     def SetMapName(self, map):
-        """Set map name"""
+        """Set map name
+
+        @param map map name to be set up or None (will close currently edited map)
+        """
         Debug.msg (3, "AbstractDigit.SetMapName map=%s" % map)
         self.map = map
 
         self.driver.Reset(self.map)
+        if not USEVEDIT:
+            self.digit.InitCats()
         
 class VEdit(AbstractDigit):
     """
@@ -161,16 +184,24 @@
     Note: This should be replaced by VDigit class.
     """
     def __init__(self, mapwindow, settings=None):
+        """Initialization
+
+        @param mapwindow reference to mapwindow (MapFrame) instance
+        @param settings  initial settings of digitization tool
+        """
         AbstractDigit.__init__(self, mapwindow, settings)
 
-    def AddPoint (self, map, type, x, y, z=None):
+    def AddPoint (self, map, point, x, y, z=None):
+        """Add point/centroid to the vector map layer
+
+        @param map   map name
+        @param point feature type (True for point, otherwise centroid)
+        @param x,y,z coordinates
         """
-        Add point/centroid to the vector map layer
-        """
-        if type == "centroid":
+        if point:
+            key = "P"
+        else:
             key = "C"
-        else:
-            key = "P"
 
         layer = self.settings["layer"]
         cat   = self.SetCategory()
@@ -194,22 +225,25 @@
                 
         self.__AddFeature (map=map, input=addstring)
 
-    def AddLine (self, map, type, coords):
+    def AddLine (self, map, line, coords):
+        """Add line/boundary to the vector map layer
+
+        @param map  map name
+        @param line feature type (True for line, otherwise boundary)
+        @param list of coordinates
         """
-        Add line/boundary to the vector map layer
-        """
         if len(coords) < 2:
             return
 
         layer = self.settings["layer"]
         cat   = self.SetCategory()
         
-        if type == "boundary":
+        if line:
+            key = "L"
+            flags = []
+        else:
             key = "B"
             flags = ['-c'] # close boundaries
-        else:
-            key = "L"
-            flags = []
             
         if layer > 0 and cat != "None":
             addstring = "%s %d 1\n" % (key, len(coords))
@@ -233,10 +267,12 @@
         self.__AddFeature (map=map, input=addstring, flags=flags)
 
     def __AddFeature (self, map, input, flags=[]):
+        """General method for adding feature to the vector map layer
+
+        @param map   map name
+        @param input feature definition in GRASS ASCII format
+        @param flags additional flags
         """
-        General method which adds feature to the vector map
-        """
-                        
         if self.settings['snapping'][0] <= 0:
             snap = "no"
         else:
@@ -267,7 +303,6 @@
         
     def DeleteSelectedLines(self):
         """Delete selected vector features from the vector map"""
-
         selected = self.driver.GetSelected() # grassId
 
         if len(selected) <= 0:
@@ -292,16 +327,27 @@
         return True
 
     def MoveSelectedLines(self, move):
-        """Move selected vector features"""
+        """Move selected vector features
+
+        @param move X,Y direction
+        """
         return self.__MoveFeature("move", None, move)
 
     def MoveSelectedVertex(self, coords, move):
-        """Move selected vertex of the line"""
+        """Move selected vertex of the line
+
+        @param coords click coordinates
+        @param move   X,Y direction
+        """
         return self.__MoveFeature("vertexmove", coords, move)
 
     def __MoveFeature(self, tool, coords, move):
-        """Move selected vector feature or vertex"""
+        """Move selected vector feature or vertex
 
+        @param tool   tool for v.edit
+        @param coords click coordinates
+        @param move   X,Y direction
+        """
         selected = self.driver.GetSelected()
 
         if len(selected) <= 0:
@@ -342,8 +388,10 @@
         return True
 
     def SplitLine(self, coords):
-        """Split selected line on position 'coords'"""
+        """Split selected line on position 'coords'
 
+        @param coords coordinates to split line
+        """
         try:
             line = self.driver.GetSelected()[0]
         except:
@@ -365,15 +413,25 @@
         return True
 
     def AddVertex(self, coords):
-        """Add new vertex to the selected line on position 'coords'"""
+        """Add new vertex to the selected line on position 'coords'
+
+        @param coords coordinates to add vertex
+        """
         return self.__ModifyVertex(coords, "vertexadd")
 
     def RemoveVertex(self, coords):
-        """Remove vertex from the selected line on position 'coords'"""
+        """Remove vertex from the selected line on position 'coords'
+
+        @param coords coordinates to remove vertex
+        """
         return self.__ModifyVertex(coords, "vertexdel")
     
     def __ModifyVertex(self, coords, action):
-        
+        """Generic method for vertex manipulation
+
+        @param coords coordinates
+        @param action operation to perform
+        """
         try:
             line = self.driver.GetSelected()[0]
         except:
@@ -395,7 +453,11 @@
         return True
 
     def CopyCats(self, cats, ids):
-        """Copy given categories to objects with id listed in ids"""
+        """Copy given categories to objects with id listed in ids
+
+        @param cats list of cats to be copied
+        @param ids  ids of lines to be modified
+        """
         if len(cats) == 0 or len(ids) == 0:
             return False
 
@@ -413,7 +475,11 @@
         return True
 
     def EditLine(self, line, coords):
-        """Edit existing line"""
+        """Edit existing line
+
+        @param line id of line to be modified
+        @param coords list of coordinates of modified line
+        """
         # remove line
         vEditDelete = gcmd.Command(['v.edit',
                                    '--q',
@@ -429,8 +495,10 @@
         self.driver.ReloadMap()
 
     def __ModifyLines(self, tool):
-        """General method to modify selected lines"""
+        """Generic method to modify selected lines
 
+        @param tool operation to be performed by v.edit
+        """
         ids = self.driver.GetSelected()
 
         if len(ids) <= 0:
@@ -454,32 +522,29 @@
 
     def FlipLine(self):
         """Flip selected lines"""
-
         return self.__ModifyLines('flip')
 
     def MergeLine(self):
         """Merge selected lines"""
-
         return self.__ModifyLines('merge')
 
     def BreakLine(self):
         """Break selected lines"""
-
         return self.__ModifyLines('break')
 
     def SnapLine(self):
         """Snap selected lines"""
-
         return self.__ModifyLines('snap')
 
     def ConnectLine(self):
         """Connect selected lines"""
-
         return self.__ModifyLines('connect')
 
     def CopyLine(self, ids=None):
-        """Copy features from (background) vector map"""
-        
+        """Copy features from (background) vector map
+
+        @param ids list of line ids to be copied
+        """
         if not ids:
             ids = self.driver.GetSelected()
 
@@ -505,7 +570,7 @@
     def SelectLinesFromBackgroundMap(self, pos1, pos2):
         """Select features from background map
 
-        pos1, pos2: bounding box defifinition
+        @param pos1,pos2 bounding box defifinition
         """
 
         if self.settings['backgroundMap'] == '':
@@ -536,7 +601,10 @@
         return ids
 
     def SelectLinesByQuery(self, pos1, pos2):
-        """Select features by query"""
+        """Select features by query
+
+        @param pos1, pos2 bounding box definition
+        """
         if self.settings['query'][0] == "length":
             thresh = self.settings['queryLength'][1]
             if self.settings["queryLength"][0] == "shorter than":
@@ -591,8 +659,12 @@
 
     def ZBulkLine(self, pos1, pos2, value, step):
         """Provide z bulk-labeling (automated assigment of z coordinate
-        to 3d lines"""
-        
+        to 3d lines
+
+        @param pos1,pos2 bounding box definition for selecting lines to be labeled
+        @param value starting value
+        @param step  step value
+        """
         gcmd.Command(['v.edit',
                       '--q',
                       'map=%s' % self.map,
@@ -607,31 +679,87 @@
     Under development (wxWidgets C/C++ background)
     """
     def __init__(self, mapwindow, settings=None):
+        """Initialization
+
+        @param mapwindow reference to mapwindow (MapFrame) instance
+        @param settings  initial settings of digitization tool
+        """
         AbstractDigit.__init__(self, mapwindow, settings)
 
         try:
-            from grass6_wxdriver import DigitClass
-            self.digit = DigitClass()
-        except:
+            from grass6_wxvdigit import Digit as DigitClass
+            self.digit = DigitClass(self.driver.GetDevice())
+        except ImportError, err:
+            print >> sys.stderr, "%sWARNING: Digitization tool is disabled (%s).%s" \
+                  "Detailed information in README file." % \
+                  (os.linesep, err, os.linesep)
             self.digit = None
 
-    def DeleteSelectedLines(self):
-        """Delete selected vector features from the vector map"""
+    def AddPoint (self, map, point, x, y, z=None):
+        """Add point/centroid to the vector map layer
 
-        selected = self.driver.GetSelected() # grassId
+        @param map   map name (unused)
+        @param point  feature type (if True -> point otherwise centroid)
+        @param x,y,z coordinates
+        """
+        layer = self.settings["layer"]
+        cat   = self.SetCategory()
+        
+        if point:
+            type = 0x01 # point
+        else:
+            type = 0x08 # centroid
 
-        if len(selected) <= 0:
-            return False
+        if z:
+            ret = self.digit.AddLine(type, [x, y, z], True, layer, cat)
+        else:
+            ret = self.digit.AddLine(type, [x, y], False, layer, cat)
 
-        ids = ",".join(["%d" % v for v in selected])
+        if ret == -1:
+            raise DigitError, _("Adding new feature to vector map <%s> failed") % map
+        
+    def AddLine (self, map, line, coords):
+        """Add line/boundary to the vector map layer
 
-        Debug.msg(4, "Digit.DeleteSelectedLines(): ids=%s" % \
-                      ids)
+        @param map  map name
+        @param line feature type (True for line, otherwise boundary)
+        @param list of coordinates
+        """
+        if len(coords) < 2:
+            return
 
-        self.digit.DeleteSelectedLines()
+        layer = self.settings["layer"]
+        cat   = self.SetCategory()
+
+        if line:
+            type = 0x02
+        else:
+            type = 0x04
+
+        listCoords = []
+        for c in coords:
+            for x in c:
+                listCoords.append(x)
+
+        if len(coords[0]) == 3: # with_z
+            ret = self.digit.AddLine(type, listCoords, True, layer, cat)
+        else:
+            ret = self.digit.AddLine(type, listCoords, False, layer, cat)
+
+        if ret == -1:
+            raise DigitError, _("Adding new feature to vector map <%s> failed") % map
+
+
+    def DeleteSelectedLines(self):
+        """Delete selected vector features from the vector map
+
+        @return number of deleted lines
+        """
+
+        nlines = self.digit.DeleteSelectedLines()
         #self.driver.DrawUpdatedLines()
 
-        return True
+        return nlines
 
 if USEVEDIT:
     class Digit(VEdit):
@@ -647,6 +775,11 @@
 class AbstractDisplayDriver:
     """Abstract classs for display driver"""
     def __init__(self, parent, mapwindow):
+        """Initialization
+
+        @param parent
+        @param mapwindow reference to mapwindow (MFrame)
+        """
         self.parent      = parent
         self.mapwindow   = mapwindow
         
@@ -654,7 +787,11 @@
         self.selected    = []   # list of selected objects (grassId!)
 
     def GetThreshold(self, value=None, units=None):
-        """Return threshold in map units"""
+        """Return threshold in map units
+
+        @param value threshold to be set up
+        @param units units (map, screen)
+        """
         if not value:
             value = self.parent.settings["snapping"][0]
 
@@ -682,6 +819,11 @@
     Display driver using grass6_wxdriver module
     """
     def __init__(self, parent, mapwindow):
+        """Initialization
+
+        @param parent
+        @param mapwindow reference to mapwindow (MFrame)
+        """
         AbstractDisplayDriver.__init__(self, parent, mapwindow)
 
         self.mapWindow = mapwindow
@@ -695,15 +837,28 @@
         settings = self.parent.settings
         self.UpdateSettings()
 
+    def GetDevice(self):
+        """Get device"""
+        return self.__display
+    
     def SetDevice(self, pdc):
-        """Set device for driver"""
+        """Set device for driver
+
+        @param pdc wx.PseudoDC instance
+        """
         self.__display.SetDevice(pdc)
             
     def Reset(self, map):
-        """Close map and open new one"""
+        """Close map and open new one
+
+        map map name to be set up
+        """
         if map:
             name, mapset = map.split('@')
-            self.__display.OpenMap(str(name), str(mapset))
+            if USEVEDIT:
+                ret = self.__display.OpenMap(str(name), str(mapset), False)
+            else:
+                ret = self.__display.OpenMap(str(name), str(mapset), True)
         else:
             self.__display.CloseMap()
     
@@ -718,7 +873,7 @@
     def DrawMap(self):
         """Draw vector map layer content
 
-        Return wx.Image 
+        @return wx.Image instance
         """
         import time
         start = time.clock()
@@ -733,8 +888,10 @@
         """Select vector features by given bounding box.
 
         If type is given, only vector features of given type are selected.
+
+        @param begin,end bounding box definition
+        @param type      select only objects of given type
         """
-
         x1, y1 = begin
         x2, y2 = end
 
@@ -748,8 +905,10 @@
         """Select vector feature by coordinates of click point (in given threshold).
 
         If type is given, only vector features of given type are selected.
+
+        @param point click coordinates (bounding box given by threshold)
+        @param type  select only objects of given type
         """
-
         ftype = -1 # all types
         if type:
             if type == "point":
@@ -772,9 +931,8 @@
     def GetSelected(self, grassId=True):
         """Return ids of selected vector features
         
-        If grassId is True returns GRASS ids, otherwise
+        @param grassId if grassId is True returns GRASS ids, otherwise
         internal ids of objects drawn in PseudoDC"""
-        
         if grassId:
             selected = self.__display.GetSelected(True)
         else:
@@ -787,8 +945,10 @@
 
     def GetSelectedVertex(self, coords):
         """Get PseudoDC id(s) of vertex (of selected line)
-        on position 'coords'"""
+        on position 'coords'
 
+        @param coords click position
+        """
         x, y = coords
 
         id = self.__display.GetSelectedVertex(x, y, self.GetThreshold())
@@ -799,8 +959,10 @@
         return id 
 
     def SetSelected(self, id):
-        """Set selected vector features"""
+        """Set selected vector features
 
+        @param id line id to be selected
+        """
         Debug.msg(4, "CDisplayDriver.SetSelected(): id=%s" % id)
 
         self.__display.SetSelected(id)
@@ -831,66 +993,67 @@
         if not self.__display:
             return
         
-        self.__display.SetSettings (wx.Color(settings['symbolHighlight'][1][0],
-                                           settings['symbolHighlight'][1][1],
-                                           settings['symbolHighlight'][1][2],
+        self.__display.UpdateSettings (wx.Color(settings['symbolHighlight'][1][0],
+                                                settings['symbolHighlight'][1][1],
+                                                settings['symbolHighlight'][1][2],
+                                                255).GetRGB(),
+                                       settings['symbolPoint'][0],
+                                       wx.Color(settings['symbolPoint'][1][0],
+                                                settings['symbolPoint'][1][1],
+                                                settings['symbolPoint'][1][2],
+                                                255).GetRGB(),
+                                       settings['symbolLine'][0],
+                                       wx.Color(settings['symbolLine'][1][0],
+                                                settings['symbolLine'][1][1],
+                                                settings['symbolLine'][1][2],
                                            255).GetRGB(),
-                                  settings['symbolPoint'][0],
-                                  wx.Color(settings['symbolPoint'][1][0],
-                                           settings['symbolPoint'][1][1],
-                                           settings['symbolPoint'][1][2],
-                                           255).GetRGB(),
-                                  settings['symbolLine'][0],
-                                  wx.Color(settings['symbolLine'][1][0],
-                                           settings['symbolLine'][1][1],
-                                           settings['symbolLine'][1][2],
-                                           255).GetRGB(),
-                                  settings['symbolBoundaryNo'][0],
-                                  wx.Color(settings['symbolBoundaryNo'][1][0],
-                                           settings['symbolBoundaryNo'][1][1],
-                                           settings['symbolBoundaryNo'][1][2],
-                                           255).GetRGB(),
-                                  settings['symbolBoundaryOne'][0],
-                                  wx.Color(settings['symbolBoundaryOne'][1][0],
-                                           settings['symbolBoundaryOne'][1][1],
-                                           settings['symbolBoundaryOne'][1][2],
-                                           255).GetRGB(),
-                                  settings['symbolBoundaryTwo'][0],
-                                  wx.Color(settings['symbolBoundaryTwo'][1][0],
-                                           settings['symbolBoundaryTwo'][1][1],
-                                           settings['symbolBoundaryTwo'][1][2],
-                                           255).GetRGB(),
-                                  settings['symbolCentroidIn'][0],
-                                  wx.Color(settings['symbolCentroidIn'][1][0],
-                                           settings['symbolCentroidIn'][1][1],
-                                           settings['symbolCentroidIn'][1][2],
-                                           255).GetRGB(),
-                                  settings['symbolCentroidOut'][0],
-                                  wx.Color(settings['symbolCentroidOut'][1][0],
-                                           settings['symbolCentroidOut'][1][1],
-                                           settings['symbolCentroidOut'][1][2],
-                                           255).GetRGB(),
-                                  settings['symbolCentroidDup'][0],
-                                  wx.Color(settings['symbolCentroidDup'][1][0],
-                                           settings['symbolCentroidDup'][1][1],
-                                           settings['symbolCentroidDup'][1][2],
-                                           255).GetRGB(),
-                                  settings['symbolNodeOne'][0],
-                                  wx.Color(settings['symbolNodeOne'][1][0],
-                                           settings['symbolNodeOne'][1][1],
-                                           settings['symbolNodeOne'][1][2],
-                                           255).GetRGB(),
-                                  settings['symbolNodeTwo'][0],
-                                  wx.Color(settings['symbolNodeTwo'][1][0],
-                                           settings['symbolNodeTwo'][1][1],
-                                           settings['symbolNodeTwo'][1][2],
-                                           255).GetRGB(),
-                                  settings['symbolVertex'][0],
-                                  wx.Color(settings['symbolVertex'][1][0],
-                                           settings['symbolVertex'][1][1],
-                                           settings['symbolVertex'][1][2],
-                                           255).GetRGB(),
-                                  settings['lineWidth'][0])
+                                       settings['symbolBoundaryNo'][0],
+                                       wx.Color(settings['symbolBoundaryNo'][1][0],
+                                                settings['symbolBoundaryNo'][1][1],
+                                                settings['symbolBoundaryNo'][1][2],
+                                                255).GetRGB(),
+                                       settings['symbolBoundaryOne'][0],
+                                       wx.Color(settings['symbolBoundaryOne'][1][0],
+                                                settings['symbolBoundaryOne'][1][1],
+                                                settings['symbolBoundaryOne'][1][2],
+                                                255).GetRGB(),
+                                       settings['symbolBoundaryTwo'][0],
+                                       wx.Color(settings['symbolBoundaryTwo'][1][0],
+                                                settings['symbolBoundaryTwo'][1][1],
+                                                settings['symbolBoundaryTwo'][1][2],
+                                                255).GetRGB(),
+                                       settings['symbolCentroidIn'][0],
+                                       wx.Color(settings['symbolCentroidIn'][1][0],
+                                                settings['symbolCentroidIn'][1][1],
+                                                settings['symbolCentroidIn'][1][2],
+                                                255).GetRGB(),
+                                       settings['symbolCentroidOut'][0],
+                                       wx.Color(settings['symbolCentroidOut'][1][0],
+                                                settings['symbolCentroidOut'][1][1],
+                                                settings['symbolCentroidOut'][1][2],
+                                                255).GetRGB(),
+                                       settings['symbolCentroidDup'][0],
+                                       wx.Color(settings['symbolCentroidDup'][1][0],
+                                                settings['symbolCentroidDup'][1][1],
+                                                settings['symbolCentroidDup'][1][2],
+                                                255).GetRGB(),
+                                       settings['symbolNodeOne'][0],
+                                       wx.Color(settings['symbolNodeOne'][1][0],
+                                                settings['symbolNodeOne'][1][1],
+                                                settings['symbolNodeOne'][1][2],
+                                                255).GetRGB(),
+                                       settings['symbolNodeTwo'][0],
+                                       wx.Color(settings['symbolNodeTwo'][1][0],
+                                                settings['symbolNodeTwo'][1][1],
+                                                settings['symbolNodeTwo'][1][2],
+                                                255).GetRGB(),
+                                       settings['symbolVertex'][0],
+                                       wx.Color(settings['symbolVertex'][1][0],
+                                                settings['symbolVertex'][1][1],
+                                                settings['symbolVertex'][1][2],
+                                                255).GetRGB(),
+                                       settings['lineWidth'][0],
+                                       self.GetThreshold())
 
 class DigitSettingsDialog(wx.Dialog):
     """

Modified: grass/trunk/gui/wxpython/gui_modules/mapdisp.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/mapdisp.py	2008-01-08 11:30:08 UTC (rev 29600)
+++ grass/trunk/gui/wxpython/gui_modules/mapdisp.py	2008-01-08 11:48:03 UTC (rev 29601)
@@ -906,9 +906,11 @@
             if digitToolbar.action == "addLine":
                 if digitToolbar.type in ["point", "centroid"]:
                     # add new point
-                    digitClass.AddPoint(map=map,
-                                        type=digitToolbar.type,
-                                        x=east, y=north)
+                    if digitToolbar.type == 'point':
+                        point = True
+                    else:
+                        point = False
+                    digitClass.AddPoint(map, point, east, north)
 
                     self.UpdateMap(render=False) # redraw map
 
@@ -1357,11 +1359,12 @@
                     # xy -> EN
                     # for coord in self.polycoords:
                     #    mapcoords.append(self.Pixel2Cell(coord))
+                    if digitToolbar.type == 'line':
+                        line = True
+                    else:
+                        line = False
+                    digitClass.AddLine(map, line, self.polycoords)
 
-                    digitClass.AddLine(map=map,
-                                       type=digitToolbar.type,
-                                       coords=self.polycoords)
-
                     position = self.Cell2Pixel(self.polycoords[-1])
                     self.polycoords = []
                     self.UpdateMap(render=False)

Copied: grass/trunk/gui/wxpython/vdigit (from rev 29593, grass/trunk/gui/wxpython/display_driver)

Deleted: grass/trunk/gui/wxpython/vdigit/Makefile.in
===================================================================
--- grass/trunk/gui/wxpython/display_driver/Makefile.in	2008-01-07 12:38:19 UTC (rev 29593)
+++ grass/trunk/gui/wxpython/vdigit/Makefile.in	2008-01-08 11:48:03 UTC (rev 29601)
@@ -1,38 +0,0 @@
-### DEFINITIONS
-
-PYTHONVERSION=@PYVERSION@
-
-### END DEFINITIONS
-
-MODULE_TOPDIR = ../../..
-
-include $(MODULE_TOPDIR)/include/Make/Lib.make
-include $(MODULE_TOPDIR)/include/Make/Doxygen.make
-
-SWIG=swig
-
-CFLAGS=-c -fpic -I/usr/include/python$(PYTHONVERSION) -I./ -I$(ARCH_DISTDIR)/include `wx-config --cxxflags` `gdal-config --cflags`
-
-LDFLAGS=-shared -fpic -L$(ARCH_LIBDIR) -lgrass_vect -lgrass_gis `wx-config --libs` -L./ -lgdi
-
-default: grass6_wxdriver.so
-
-clean:
-	-rm -f *.o _grass6_wxdriver.so grass6_wxdriver_wrap.cxx grass6_wxdriver.py grass6_wxdriver.i grass6_wxdriver.pyc	 
-
-grass6_wxdriver.i:
-	cat ./driver.i > grass6_wxdriver.i
-	echo "/* auto-generate swig typedef file (with some GRASS functions removed) */" >> grass6_wxdriver.i
-	cat ./driver.h >> grass6_wxdriver.i
-
-grass6_wxdriver_wrap.cxx: grass6_wxdriver.i
-	$(SWIG) -c++ -python -shadow $<
-
-grass6_wxdriver_wrap.o: grass6_wxdriver_wrap.cxx
-	$(CXX) $(CFLAGS) $(INCLUDE_DIRS) $<
-
-driver.o: driver.cpp driver.h
-	$(CXX) $(CFLAGS) $(INCLUDE_DIRS) $<
-
-grass6_wxdriver.so: grass6_wxdriver_wrap.o driver.o
-	$(CXX) $(LDFLAGS) grass6_wxdriver_wrap.o driver.o -o _grass6_wxdriver.so

Copied: grass/trunk/gui/wxpython/vdigit/Makefile.in (from rev 29600, grass/trunk/gui/wxpython/display_driver/Makefile.in)
===================================================================
--- grass/trunk/gui/wxpython/vdigit/Makefile.in	                        (rev 0)
+++ grass/trunk/gui/wxpython/vdigit/Makefile.in	2008-01-08 11:48:03 UTC (rev 29601)
@@ -0,0 +1,38 @@
+### DEFINITIONS
+
+PYTHONVERSION=@PYVERSION@
+
+### END DEFINITIONS
+
+MODULE_TOPDIR = ../../..
+
+include $(MODULE_TOPDIR)/include/Make/Lib.make
+include $(MODULE_TOPDIR)/include/Make/Doxygen.make
+
+SWIG=swig
+
+CFLAGS=-c -fpic -I/usr/include/python$(PYTHONVERSION) -I./ -I$(ARCH_DISTDIR)/include `wx-config --cxxflags` `gdal-config --cflags`
+
+LDFLAGS=-shared -fpic -L$(ARCH_LIBDIR) -lgrass_vect -lgrass_gis `wx-config --libs` -L./ -lgdi
+
+default: grass6_wxdriver.so
+
+clean:
+	-rm -f *.o _grass6_wxdriver.so grass6_wxdriver_wrap.cxx grass6_wxdriver.py grass6_wxdriver.i grass6_wxdriver.pyc	 
+
+grass6_wxdriver.i:
+	cat ./driver.i > grass6_wxdriver.i
+	echo "/* auto-generate swig typedef file (with some GRASS functions removed) */" >> grass6_wxdriver.i
+	cat ./driver.h >> grass6_wxdriver.i
+
+grass6_wxdriver_wrap.cxx: grass6_wxdriver.i
+	$(SWIG) -c++ -python -shadow $<
+
+grass6_wxdriver_wrap.o: grass6_wxdriver_wrap.cxx
+	$(CXX) $(CFLAGS) $(INCLUDE_DIRS) $<
+
+driver.o: driver.cpp driver.h
+	$(CXX) $(CFLAGS) $(INCLUDE_DIRS) $<
+
+grass6_wxdriver.so: grass6_wxdriver_wrap.o driver.o
+	$(CXX) $(LDFLAGS) grass6_wxdriver_wrap.o driver.o -o _grass6_wxdriver.so

Added: grass/trunk/gui/wxpython/vdigit/cats.cpp
===================================================================
--- grass/trunk/gui/wxpython/vdigit/cats.cpp	                        (rev 0)
+++ grass/trunk/gui/wxpython/vdigit/cats.cpp	2008-01-08 11:48:03 UTC (rev 29601)
@@ -0,0 +1,107 @@
+/**
+   \file cats.cpp
+
+   \brief Category management
+
+   This program is free software under the GNU General Public
+   License (>=v2). Read the file COPYING that comes with GRASS
+   for details.
+
+   \author (C) by The GRASS development team
+   Martin Landa <landa.martin gmail.com>
+
+   \date 2008 
+*/
+
+#include "driver.h"
+#include "digit.h"
+
+/**
+   \brief Initialize cats structure.
+
+   \return 0 on success
+   \return -1 on error
+*/
+int Digit::InitCats()
+{
+    int nfields, field, index, ncats, max_cat;
+    int cat, type, id; 
+
+    struct lcat lc;
+
+    G_debug(2, "vdigit.InitCats()");
+
+    if (!cats.empty()) {	
+	cats.clear();
+    }
+
+    if (!display->mapInfo) {
+	return -1;
+    }
+
+    nfields = Vect_cidx_get_num_fields (display->mapInfo);
+    
+    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);
+	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;
+	}
+
+	lc.layer = Vect_cidx_get_field_number(display->mapInfo, i);
+	lc.cat = max_cat;
+
+	cats.push_back(lc);
+	G_debug(3, "vdigit.InitCats(): layer=%d, cat=%d", lc.layer, lc.cat);
+    }
+
+    return 0;
+}
+
+/**
+   \brief Get max category number for layer
+
+   \param layer layer number
+
+   \return category number (1 if no category found)
+   \return -1 on error
+*/
+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;
+	}
+    }
+
+    return -1;
+}
+
+/**
+   \brief Set max category number for layer
+
+   \param layer layer number
+   \param cats  category number to be set
+
+   \return previosly set category
+*/
+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, "vdigit.SetCategory(): layer=%d, cat=%d", layer, cat);
+	}
+    }
+
+    return old_cat;
+}
+

Added: grass/trunk/gui/wxpython/vdigit/digit.cpp
===================================================================
--- grass/trunk/gui/wxpython/vdigit/digit.cpp	                        (rev 0)
+++ grass/trunk/gui/wxpython/vdigit/digit.cpp	2008-01-08 11:48:03 UTC (rev 29601)
@@ -0,0 +1,32 @@
+/**
+   \file digit.cpp
+
+   \brief Experimental C++ interace for vector digitization used
+   by wxPython GUI.
+
+   This program is free software under the GNU General Public
+   License (>=v2). Read the file COPYING that comes with GRASS
+   for details.
+
+   \author (C) by the GRASS Development Team
+   Martin Landa <landa.martin gmail.com>
+
+   \date 2008
+*/
+
+#include "driver.h"
+#include "digit.h"
+
+/**
+   \brief Initialize digit interface used by SWIG
+
+   \param driver display driver instance
+*/
+Digit::Digit(DisplayDriver *ddriver)
+{
+    display = ddriver;
+
+    if (display->mapInfo) {
+	InitCats();
+    }
+}

Added: grass/trunk/gui/wxpython/vdigit/digit.h
===================================================================
--- grass/trunk/gui/wxpython/vdigit/digit.h	                        (rev 0)
+++ grass/trunk/gui/wxpython/vdigit/digit.h	2008-01-08 11:48:03 UTC (rev 29601)
@@ -0,0 +1,30 @@
+#ifndef __DIGIT_H__
+#define __DIGIT_H__
+
+class Digit
+{
+private:
+    struct lcat {
+	int layer;
+	int cat;
+    };
+    std::vector<lcat> cats;
+
+    DisplayDriver *display;
+
+    int SetCategory(int, int);
+
+public:
+    Digit(DisplayDriver *);
+
+    int InitCats();
+
+    int AddLine(int, std::vector<double>, bool, int, int);
+    int DeleteSelectedLines();
+
+    int GetCategory(int);
+
+};
+
+#endif /* __DIGIT_H__ */
+

Added: grass/trunk/gui/wxpython/vdigit/digit.i
===================================================================
--- grass/trunk/gui/wxpython/vdigit/digit.i	                        (rev 0)
+++ grass/trunk/gui/wxpython/vdigit/digit.i	2008-01-08 11:48:03 UTC (rev 29601)
@@ -0,0 +1,17 @@
+/* File: digit.i */
+
+%module grass6_wxvdigit
+%{
+#include <grass/gis.h>
+#include <grass/gisdefs.h>
+#include <grass/Vect.h>
+#include <grass/vect/dig_structs.h>
+#include "driver.h"
+#include "digit.h"
+%}
+
+%include "std_vector.i" 
+namespace std { 
+   %template(IntVector) vector<int>;
+   %template(DoubleVector) vector<double>;
+}

Deleted: grass/trunk/gui/wxpython/vdigit/driver.cpp
===================================================================
--- grass/trunk/gui/wxpython/display_driver/driver.cpp	2008-01-07 12:38:19 UTC (rev 29593)
+++ grass/trunk/gui/wxpython/vdigit/driver.cpp	2008-01-08 11:48:03 UTC (rev 29601)
@@ -1,1066 +0,0 @@
-/**
-   \file driver.cpp
-   
-   \brief Experimental C++ wxWidgets display driver
-
-   This driver is designed for wxPython GRASS GUI (digitization tool).
-   Draw vector map layer to PseudoDC.
-
-   \author Martin Landa <landa.martin gmail.com>
-
-   (C) 2007 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.
-*/
-
-#include "driver.h"
-
-/**
-   \brief Initialize driver
-
-   Allocate given structures.
-   
-   \param[in,out] PseudoDC device where to draw vector objects
-   
-   \return
-*/
-DisplayDriver::DisplayDriver(void *device)
-{
-    G_gisinit(""); /* GRASS functions */
-
-    mapInfo = NULL;
-
-    dc = (wxPseudoDC *) device;
-
-    points       = Vect_new_line_struct();
-    pointsScreen = new wxList();
-    cats         = Vect_new_cats_struct();
-
-    drawSegments = false;
-}
-
-/**
-   \brief Destroy driver
-
-   Close the map, deallocate given structures.
-
-   \param
-
-   \return
-*/
-DisplayDriver::~DisplayDriver()
-{
-    if (mapInfo)
-	CloseMap();
-
-    Vect_destroy_line_struct(points);
-    delete pointsScreen;
-    Vect_destroy_cats_struct(cats);
-}
-
-/**
-   \brief Set device for drawing
-   
-   \param[in,out] PseudoDC device where to draw vector objects
-
-   \return
-*/
-void DisplayDriver::SetDevice(void *device)
-{
-    dc = (wxPseudoDC *) device;
-
-    return;
-}
-
-/**
-   \brief Draw content of the vector map to device
-   
-   \return number of lines which were drawn
-   \return -1 on error
- */
-int DisplayDriver::DrawMap(bool force)
-{
-    if (!mapInfo || !dc)
-	return -1;
-
-    int nlines;
-    BOUND_BOX mapBox;
-    struct ilist *listLines;
-
-    // ids.clear();
-    listLines = Vect_new_list();
-
-    ResetTopology();
-
-    /* nlines = Vect_get_num_lines(mapInfo); */
-
-    //Vect_build_partial(mapInfo, GV_BUILD_NONE, stderr);
-    //Vect_build(mapInfo, stderr);
-
-    Vect_get_map_box(mapInfo, &mapBox);
-
-    // draw lines inside of current display region
-    nlines = Vect_select_lines_by_box(mapInfo, &(region.box),
-     				      GV_POINTS | GV_LINES, // fixme
-				      listLines);
-    /*
-    nlines = Vect_select_lines_by_box(mapInfo, &mapBox,
-				      GV_POINTS | GV_LINES, // fixme
- 				      listLines);
-
-    for (int i = 0; i < listLines->n_values; i++) {
-	DrawLine(listLines->value[i]);
-    }
-    */
-
-#ifdef DEBUG
-    std::cerr.flags(std::ios_base::fixed);
-    std::cerr << "region: W=" << region.box.W
-	      << "; E=" << region.box.E
-	      << "; S=" << region.box.S
-	      << "; N=" << region.box.N << std::endl;
-
-    std::cerr << "-> nlines=" << nlines << std::endl;
-#endif
-
-    bool inBox;
-    dc->BeginDrawing();
-    for (int i = 0; i < listLines->n_values; i++) {
-	DrawLine(listLines->value[i]);
-    }
-    dc->EndDrawing();
-
-#ifdef DEBUG
-    PrintIds();
-#endif
-
-    Vect_destroy_list(listLines);
-
-    return listLines->n_values;
-}	
-
-/**
-   \brief Draw selected vector objects to the device
- 
-   \param[in] line id
-   \return 1 on success
-   \return -1 on failure (vector object is dead, etc.)
-*/
-int DisplayDriver::DrawLine(int line)
-{
-    if (!dc || !Vect_line_alive (mapInfo, line))
-	return -1;
-
-    int dcId;    // 0 | 1 | segment id
-    int type;    // line type
-    double x, y, z; // screen coordinates
-    bool draw;   // draw object ?
-
-    wxPen *pen;
-
-    // read line
-    type = Vect_read_line (mapInfo, points, cats, line);
-
-    // add ids
-    // -> node1, line1, vertex1, line2, ..., node2
-    // struct lineDesc desc = {points->n_points, dcId};
-    // ids[line] = desc;
-    // update id for next line
-    // dcId += points->n_points * 2 - 1;
-
-    if (IsSelected(line)) { // line selected ?
-	pen = new wxPen(settings.highlight, settings.lineWidth, wxSOLID);
-	draw = true;
-	dcId = 1;
-	topology.highlight++;
-    }
-    else {
-	dcId = 0;
-	if (type & GV_LINES) {
-	    switch (type) {
-	    case GV_LINE:
-		pen = new wxPen(settings.line.color, settings.lineWidth, wxSOLID);
-		topology.line++;
-		draw = settings.line.enabled;
-		break;
-	    case GV_BOUNDARY:
-		int left, right;
-		Vect_get_line_areas(mapInfo, line,
-				    &left, &right);
-		if (left == 0 && right == 0) {
-		    pen = new wxPen(settings.boundaryNo.color, settings.lineWidth, wxSOLID);
-		    topology.boundaryNo++;
-		    draw = settings.boundaryNo.enabled;
-		}
-		else if (left > 0 && right > 0) {
-		    pen = new wxPen(settings.boundaryTwo.color, settings.lineWidth, wxSOLID);
-		    topology.boundaryTwo++;
-		    draw = settings.boundaryTwo.enabled;
-		}
-		else {
-		    pen = new wxPen(settings.boundaryOne.color, settings.lineWidth, wxSOLID);
-		    topology.boundaryOne++;
-		    draw = settings.boundaryOne.enabled;
-		}
-		break;
-	    default:
-		draw = false;
-		break;
-	    }
-	}
-	else if (type & GV_POINTS) {
-	    if (type == GV_POINT && settings.point.enabled) {
-		pen = new wxPen(settings.point.color, settings.lineWidth, wxSOLID);
-		topology.point++;
-		draw = settings.point.enabled;
-	    }
-	    else if (type == GV_CENTROID) {
-		int cret = Vect_get_centroid_area(mapInfo, line);
-		if (cret > 0) { // -> area
-		    draw = settings.centroidIn.enabled;
-		    pen = new wxPen(settings.centroidIn.color, settings.lineWidth, wxSOLID);
-		    topology.centroidIn++;
-		}
-		else if (cret == 0) {
-		    draw = settings.centroidOut.enabled;
-		    pen = new wxPen(settings.centroidOut.color, settings.lineWidth, wxSOLID);
-		    topology.centroidOut++;
-		}
-		else {
-		    draw = settings.centroidDup.enabled;
-		    pen = new wxPen(settings.centroidDup.color, settings.lineWidth, wxSOLID);
-		    topology.centroidDup++;
-		}
-	    }
-	}
-    }
-    
-    // clear screen points & convert EN -> xy
-    pointsScreen->Clear();
-    for (int i = 0; i < points->n_points; i++) {
-	Cell2Pixel(points->x[i], points->y[i], points->z[i],
-		   &x, &y, &z);
-	pointsScreen->Append((wxObject*) new wxPoint((int) x, (int) y)); /* TODO: 3D */
-    }
-    
-    dc->SetId(dcId); /* 0 | 1 (selected) */
-    dc->SetPen(*pen);
-
-    if (draw) {
-	if (type & GV_POINTS) {
-	    DrawCross(line, (const wxPoint *) pointsScreen->GetFirst()->GetData());
-	}
-	else {
-	    // long int startId = ids[line].startId + 1;
-	    if (dcId > 0 && drawSegments) {
-		dcId = 2; // first segment
-		for (int i = 0; i < pointsScreen->GetCount() - 1; dcId += 2) {
-		wxPoint *point_beg = (wxPoint *) pointsScreen->Item(i)->GetData();
-		wxPoint *point_end = (wxPoint *) pointsScreen->Item(++i)->GetData();
-
-		// set bounds for line
-		// wxRect rect (*point_beg, *point_end);
-		// dc->SetIdBounds(startId, rect);
-		
-		dc->SetId(dcId); // set unique id & set bbox for each segment
-		dc->SetPen(*pen);
-		wxRect rect (*point_beg, *point_end);
-		dc->SetIdBounds(dcId, rect);
-		dc->DrawLine(point_beg->x, point_beg->y,
-			     point_end->x, point_end->y);
-		}
-	    }
-	    else {
-		wxPoint points[pointsScreen->GetCount()];
-		for (int i = 0; i < pointsScreen->GetCount(); i++) {
-		    wxPoint *point_beg = (wxPoint *) pointsScreen->Item(i)->GetData();
-		    points[i] = *point_beg;
-		}
-		dc->DrawLines(pointsScreen->GetCount(), points);
-	    }
-	}
-    }
-
-    if (type & GV_LINES) {
-	DrawLineVerteces(line); // draw vertices
-	DrawLineNodes(line);    // draw nodes
-    }
-
-    delete pen;
-
-    return 1;
-}
-
-/**
-   \brief Draw line verteces to the device
- 
-   Except of first and last vertex, see DrawLineNodes().
-
-   \param line id
-
-   \return number of verteces which were drawn
-   \return -1 if drawing vertices is disabled
-*/
-int DisplayDriver::DrawLineVerteces(int line)
-{
-    int dcId;
-    wxPoint *point;
-    wxPen *pen;
-
-    if (!IsSelected(line) && !settings.vertex.enabled)
-	return -1;
-
-    // determine color
-    if (!IsSelected(line)) {
-	pen = new wxPen(settings.vertex.color, settings.lineWidth, wxSOLID);
-	dcId = 0;
-    }
-    else {
-	pen = new wxPen(settings.highlight, settings.lineWidth, wxSOLID);
-	if (drawSegments) {
-	    dcId = 3; // first vertex
-	}
-	else {
-	    dcId = 1;
-	}
-    }
-
-    dc->SetId(dcId); /* 0 | 1 (selected) */
-    dc->SetPen(*pen);
-
-    for (int i = 1; i < pointsScreen->GetCount() - 1; i++, dcId += 2) {
-	point = (wxPoint*) pointsScreen->Item(i)->GetData();
-
-	if (IsSelected(line) && drawSegments) {
-	    dc->SetId(dcId);
-	    dc->SetPen(*pen);
-	    wxRect rect (*point, *point);
-	    dc->SetIdBounds(dcId, rect);
-	}
-	
-	if (settings.vertex.enabled) {
-	    DrawCross(line, (const wxPoint*) pointsScreen->Item(i)->GetData());
-	    topology.vertex++;
-	}
-    }
-
-    delete pen;
-
-    return pointsScreen->GetCount() - 2;
-}
-
-/**
-   \brief Draw line nodes to the device
- 
-   \param line id
-
-   \return 1
-   \return -1 if no nodes were drawn
-*/
-int DisplayDriver::DrawLineNodes(int line)
-{
-    int dcId;
-    int node;
-    double east, north, depth;
-    double x, y, z;
-    int nodes [2];
-    bool draw;
-
-    wxPen *pen;
-
-    // draw nodes??
-    if (!settings.nodeOne.enabled && !settings.nodeTwo.enabled)
-	return -1;
-
-    // get nodes
-    Vect_get_line_nodes(mapInfo, line, &(nodes[0]), &(nodes[1]));
-        
-    for (int i = 0; i < sizeof(nodes) / sizeof(int); i++) {
-	node = nodes[i];
-	// get coordinates
-	Vect_get_node_coor(mapInfo, node,
-			   &east, &north, &depth);
-
-	// convert EN->xy
-	Cell2Pixel(east, north, depth,
-		   &x, &y, &z);
-
-	// determine color
-	if (IsSelected(line)) {
-	    pen = new wxPen(settings.highlight, settings.lineWidth, wxSOLID);
-	    draw = true;
-	    if (!drawSegments) {
-		dcId = 1;
-	    }
-	    else {
-		// node1, line1, vertex1, line2, vertex2, ..., node2
-		if (i == 0) // first node
-		    dcId = 1; 
-		else // last node
-		    dcId = 2 * points->n_points - 1;
-	    }
-	}
-	else {
-	    dcId = 0;
-	    if (Vect_get_node_n_lines(mapInfo, node) == 1) {
-		pen = new wxPen(settings.nodeOne.color, settings.lineWidth, wxSOLID);
-		topology.nodeOne++;
-		draw = settings.nodeOne.enabled;
-	    }
-	    else {
-		pen = new wxPen(settings.nodeTwo.color, settings.lineWidth, wxSOLID);
-		topology.nodeTwo++;
-		draw = settings.nodeTwo.enabled;
-	    }
-	}
-	
-	wxPoint point((int) x, (int) y);
-	if (IsSelected(line) && drawSegments) {
-	    wxRect rect (point, point);
-	    dc->SetIdBounds(dcId, rect);
-	}
-
-	// draw node if needed
-	if (draw) {
-	    dc->SetId(dcId);
-	    dc->SetPen(*pen);
-	    DrawCross(line, &point);
-	}
-    }
-    
-    delete pen;
-
-    return 1;
-}
-
-
-/*
-  \brief Close vector map layer
-  
-  \param
-
-  \return
-*/
-void DisplayDriver::CloseMap()
-{
-    if (mapInfo) {
-	Vect_close(mapInfo);
-	G_free ((void *) mapInfo);
-	mapInfo = NULL;
-    }
-    
-    return;
-}
-
-/**
-   \brief Open vector map layer
- 
-   \param[in] mapname name of vector map
-   \param[in] mapset name of mapset where the vector map layer is stored
-   
-   \return
-*/
-void DisplayDriver::OpenMap(const char* mapname, const char *mapset)
-{
-    if (!mapInfo)
-	mapInfo = (struct Map_info *) G_malloc (sizeof (struct Map_info));
-
-    // define open level (level 2: topology)
-    Vect_set_open_level(2);
-
-    // open existing map
-    Vect_open_old(mapInfo, (char*) mapname, (char *) mapset);
-
-    return;
-}
-
-/**
-   \brief Reload vector map layer
-
-   Close and open again. Needed for modification using v.edit.
-
-   TODO: Get rid of that...
-
-   \param
-   
-   \return
-*/
-void DisplayDriver::ReloadMap()
-{
-    // char* name   = G_store(Vect_get_map_name(mapInfo)); ???
-    char* name   = G_store(mapInfo->name);
-    char* mapset = G_store(Vect_get_mapset(mapInfo));
-
-    Vect_close(mapInfo);
-    mapInfo = NULL;
-
-    OpenMap(name, mapset);
-    //Vect_build_partial(mapInfo, GV_BUILD_NONE, stderr);
-    //Vect_build(mapInfo, stderr);
-
-    return;
-}
-
-/*
-  \brief Conversion from geographic coordinates (east, north)
-  to screen (x, y)
-  
-  TODO: 3D stuff...
-
-  \param[in] east,north,depth geographical coordinates
-  \param[out] x, y, z screen coordinates
-  
-  \return 
-*/
-void DisplayDriver::Cell2Pixel(double east, double north, double depth,
-			       double *x, double *y, double *z)
-{
-    double n, w;
-    /*
-    *x = int((east  - region.map_west) / region.map_res);
-    *y = int((region.map_north - north) / region.map_res);
-    */
-    w = region.center_easting  - (region.map_width / 2)  * region.map_res;
-    n = region.center_northing + (region.map_height / 2) * region.map_res;
-
-    /*
-    *x = int((east  - w) / region.map_res);
-    *y = int((n - north) / region.map_res);
-    */
-    *x = (east  - w) / region.map_res;
-    *y = (n - north) / region.map_res;
-
-    *z = 0;
-
-    return;
-}
-
-/**
-   \brief Set geographical region
- 
-   Region must be upgraded because of Cell2Pixel().
-   
-   \param[in] north,south,east,west,ns_res,ew_res region settings
- 
-   \return
-*/
-void DisplayDriver::SetRegion(double north, double south, double east, double west,
-			      double ns_res, double ew_res,
-			      double center_easting, double center_northing,
-			      double map_width, double map_height)
-{
-    region.box.N  = north;
-    region.box.S  = south;
-    region.box.E  = east;
-    region.box.W  = west;
-    region.box.T  = PORT_DOUBLE_MAX;
-    region.box.B  = -PORT_DOUBLE_MAX;
-    region.ns_res = ns_res;
-    region.ew_res = ew_res;
-
-    region.center_easting = center_easting;
-    region.center_northing = center_northing;
-
-    region.map_width  = map_width;
-    region.map_height = map_height;
-
-#ifdef DEBUG
-    std::cerr << "region: n=" << north
-	      << "; s=" << south
-	      << "; e=" << east
-	      << "; w=" << west
-	      << "; ns_res=" << ns_res
-	      << "; ew_res=" << ew_res
-	      << "; center_easting=" << center_easting
-	      << "; center_northing=" << center_northing
-	      << "; map_width=" << map_width
-	      << "; map_height=" << map_height
-	      << std::endl;
-#endif
-
-    // calculate real region
-    region.map_res = (region.ew_res > region.ns_res) ? region.ew_res : region.ns_res;
-
-    region.map_west  = region.center_easting - (region.map_width / 2.) * region.map_res;
-    region.map_north = region.center_northing + (region.map_height / 2.) * region.map_res;
-
-    return;
-}
-
-/**
-   \brief Draw cross symbol of given size to device content
-   
-   Used for points, nodes, vertices
-
-   \param[in] point coordinates of center
-   \param[in] size size of the cross symbol
-   
-   \return 1 on success
-   \return -1 on failure
-*/
-int DisplayDriver::DrawCross(int line, const wxPoint* point, int size)
-{
-    if (!dc || !point)
-	return -1;
-
-    dc->DrawLine(point->x - size, point->y, point->x + size, point->y);
-    dc->DrawLine(point->x, point->y - size, point->x, point->y + size);
-    return 1;
-}
-
-/*
-  \brief Set settings for displaying vector feature
- 
-  E.g. line width, color, ...
-  
-  \param[in] lineWidth,... settgings
-  
-  \return 
-*/
-void DisplayDriver::SetSettings(unsigned long highlight,
-				bool ePoint,       unsigned long cPoint, /* enabled, color */
-				bool eLine,        unsigned long cLine,
-				bool eBoundaryNo,  unsigned long cBoundaryNo,
-				bool eBoundaryOne, unsigned long cBoundaryOne,
-				bool eBoundaryTwo, unsigned long cBoundaryTwo,
-				bool eCentroidIn,  unsigned long cCentroidIn,
-				bool eCentroidOut, unsigned long cCentroidOut,
-				bool eCentroidDup, unsigned long cCentroidDup,
-				bool eNodeOne,     unsigned long cNodeOne,
-				bool eNodeTwo,     unsigned long cNodeTwo,
-				bool eVertex,      unsigned long cVertex,
-				int lineWidth)
-{
-    settings.highlight.Set(highlight);
-
-    settings.point.enabled = ePoint;
-    settings.point.color.Set(cPoint);
-
-    settings.line.enabled = eLine;
-    settings.line.color.Set(cLine);
-
-    settings.boundaryNo.enabled = eBoundaryNo;
-    settings.boundaryNo.color.Set(cBoundaryNo);
-    settings.boundaryOne.enabled = eBoundaryOne;
-    settings.boundaryOne.color.Set(cBoundaryOne);
-    settings.boundaryTwo.enabled = eBoundaryTwo;
-    settings.boundaryTwo.color.Set(cBoundaryTwo);
-
-
-    settings.centroidIn.enabled = eCentroidIn;
-    settings.centroidIn.color.Set(cCentroidIn);
-    settings.centroidOut.enabled = eCentroidOut;
-    settings.centroidOut.color.Set(cCentroidOut);
-    settings.centroidDup.enabled = eCentroidDup;
-    settings.centroidDup.color.Set(cCentroidDup);
-
-    settings.nodeOne.enabled = eNodeOne;
-    settings.nodeOne.color.Set(cNodeOne);
-    settings.nodeTwo.enabled = eNodeTwo;
-    settings.nodeTwo.color.Set(cNodeTwo);
-
-    settings.vertex.enabled = eVertex;
-    settings.vertex.color.Set(cVertex);
-
-
-    settings.lineWidth = lineWidth;
-    
-}
-
-/**
-   \brief Prints gId: dcIds
-
-   Useful for debugging purposes.
-
-   \param
-
-   \return
-*/
-void DisplayDriver::PrintIds()
-{
-    /*
-      for (ids_map::const_iterator i = ids.begin(), e = ids.end();
-      i != e; ++i) {
-      std::cerr << "line=" << i->first << ": "
-      << "npoints=" << i->second.npoints
-      << " startId=" << i->second.startId
-      << std::endl;
-      }
-    */
-
-    std::cerr << "topology.highlight: " << topology.highlight << std::endl;
-
-    std::cerr << "topology.point: " << topology.point << std::endl;
-    std::cerr << "topology.line: " << topology.line << std::endl;
-
-    std::cerr << "topology.boundaryNo: " << topology.boundaryNo << std::endl;
-    std::cerr << "topology.boundaryOne: " << topology.boundaryOne << std::endl;
-    std::cerr << "topology.boundaryTwo: " << topology.boundaryTwo << std::endl;
-
-    std::cerr << "topology.centroidIn: " << topology.centroidIn << std::endl;
-    std::cerr << "topology.centroidOut: " << topology.centroidOut << std::endl;
-    std::cerr << "topology.centroidDup: " << topology.centroidDup << std::endl;
-
-    std::cerr << "topology.nodeOne: " << topology.nodeOne << std::endl;
-    std::cerr << "topology.nodeTwo: " << topology.nodeTwo << std::endl;
-
-    std::cerr << "topology.vertex: " << topology.vertex << std::endl;
-
-    std::cerr << std::endl << "nobjects: "
-	      << topology.point * 2 + // cross
-      topology.line + 
-      topology.boundaryNo +
-      topology.boundaryOne +
-      topology.boundaryTwo +
-      topology.centroidIn * 2 +
-      topology.centroidOut * 2 +
-      topology.centroidDup * 2 +
-      topology.nodeOne * 2 +
-      topology.nodeTwo * 2 +
-      topology.vertex * 2 << std::endl;
-
-    std::cerr << "selected: ";
-    for (std::vector<int>::const_iterator i = selected.begin(), e = selected.end();
-	 i != e; ++i)
-	std::cerr << *i << " ";
-    std::cerr << std::endl;
-
-    return;
-}
-
-/**
-   \brief Select vector objects by given bounding box
-   
-   If line id is already in the list of selected lines, then it will
-   be excluded from this list.
-
-   \param[in] x1,y1,x2,y2 corners coordinates of bounding box
-
-   \return number of selected features
-   \return -1 on error
-*/
-int DisplayDriver::SelectLinesByBox(double x1, double y1, double x2, double y2)
-{
-    if (!mapInfo)
-	return -1;
-
-    int type, line;
-    double dx, dy;
-
-    struct ilist *list;
-    struct line_pnts *bbox;
-
-    type = -1; // all types
-
-    list = Vect_new_list();
-    bbox = Vect_new_line_struct();
-
-    dx = std::fabs(x2 - x1);
-    dy = std::fabs(y2 - y1);
-        
-    Vect_append_point(bbox, x1, y1, -PORT_DOUBLE_MAX);
-    Vect_append_point(bbox, x2, y1,  PORT_DOUBLE_MAX);
-    Vect_append_point(bbox, x2, y2, -PORT_DOUBLE_MAX);
-    Vect_append_point(bbox, x1, y2,  PORT_DOUBLE_MAX);
-    Vect_append_point(bbox, x1, y1, -PORT_DOUBLE_MAX);
-        
-    Vect_select_lines_by_polygon(mapInfo, bbox,
-				 0, NULL,
-				 type, list);
-	
-    for (int i = 0; i < list->n_values; i++) {
-	line = list->value[i];
-	if (!IsSelected(line)) {
-	    selected.push_back(line);
-	}
-	else {
-	    selected.erase(GetSelectedIter(line));
-	}
-    }
-
-    // remove all duplicate ids
-    sort(selected.begin(), selected.end());
-    selected.erase(unique(selected.begin(), selected.end()), selected.end());
-
-    Vect_destroy_line_struct(bbox);
-    Vect_destroy_list(list);
-
-    return selected.size();
-}
-
-/**
-   \brief Select vector feature by given point in given
-   threshold
-   
-   Only one vector object can be selected. Bounding boxes of
-   all segments are stores.
-
-   \param[in] x,y point of searching
-   \param[in] thresh threshold value where to search
-   \param[in] onlyType select vector object of given type
-
-   \return point on line if line found
-*/
-std::vector<double> DisplayDriver::SelectLineByPoint(double x, double y, double thresh,
-						     int type)
-{
-    long int line;
-    int ftype;
-    double px, py, pz;
-
-    std::vector<double> p;
-
-    if (type == -1) {
-	ftype = GV_POINTS | GV_LINES;
-    }
-    else if (type == 0) {
-	ftype = GV_POINTS;
-    }
-    else if (type == 1) {
-	ftype = GV_LINES;
-    }
-
-    line = Vect_find_line(mapInfo, x, y, 0.0,
-			  ftype, thresh, 0, 0);
-
-    if (line > 0) {
-	selected.push_back(line);
-	type = Vect_read_line (mapInfo, points, cats, line);
-	Vect_line_distance (points, x, y, 0.0, WITHOUT_Z,
-			    &px, &py, &pz,
-			    NULL, NULL, NULL);
-	p.push_back(px);
-	p.push_back(py);
-    }
-
-    drawSegments = true;
-
-    return p;
-}
-
-/**
-   \brief Is vector object selected?
-   
-   \param[in] line id
-
-   \return true if vector object is selected
-   \return false if vector object is not selected
-*/
-bool DisplayDriver::IsSelected(int line)
-{
-    if (GetSelectedIter(line) != selected.end())
-	return true;
-
-    return false;
-}
-
-/**
-   \brief Is vector object selected?
-   
-   \param[in] line id
-
-   \return item iterator
-   \return selected.end() if object is not selected
-*/
-std::vector<int>::iterator DisplayDriver::GetSelectedIter(int line)
-{
-    for(std::vector<int>::iterator i = selected.begin(), e = selected.end();
-	i != e; ++i) {
-	if (line == *i)
-	    return i;
-    }
-
-    return selected.end();
-}
-
-/**
-   \brief Get ids of selected objects
-
-   \param[in] grassId if true return GRASS line ids
-   if false return PseudoDC ids
-   
-   \return list of ids of selected vector objects
-*/
-std::vector<int> DisplayDriver::GetSelected(bool grassId)
-{
-    if (grassId)
-	return selected;
-
-    std::vector<int> dc_ids;
-    long int line;
-
-    if (!drawSegments) {
-	dc_ids.push_back(1);
-    }
-    else {
-	int npoints;
-	Vect_read_line(mapInfo, points, NULL, selected[0]);
-	npoints = points->n_points;
-	for (int i = 1; i < 2 * npoints; i++) {
-	  dc_ids.push_back(i);
-	}
-    }
-
-    /*
-    for(std::vector<int>::const_iterator i = selected.begin(), e = selected.end();
-	i != e; ++i) {
-	line = *i;
-	ids_map::const_iterator ii = ids.find(line);
-	if (ii != ids.end()) { // line found
-	    long int endId = ii->second.npoints * 2 - 1 + ii->second.startId;
-	    int type, i;
-	    int vx, vy, vz;
-	    type = Vect_read_line (mapInfo, points, cats, line);
-	    i = 0;
- 	    for (long int id = ii->second.startId; id < endId; id++) {
-		dc_ids.push_back(id);
-                // set bounding boxes for all selected objects (only nodes)
-		if (id % 2) {
-		    Cell2Pixel(points->x[i], points->y[i], points->z[i],
-			       &vx, &vy, &vz);
-		    wxRect rect (wxPoint (vx, vy), wxPoint (vx, vy));
-		    dc->SetIdBounds(id, rect);
-
-		    i++;
-		}
-
-	    }
-	}
-    }
-    */
-
-    return dc_ids;
-}
-
-/**
-   \brief Set selected vector objects
-   
-   \param[in] list of GRASS ids to be set
-
-   \return 1
-*/
-int DisplayDriver::SetSelected(std::vector<int> id)
-{
-    selected = id;
-
-    if (selected.size() <= 0)
-	drawSegments = false;
-
-    return 1;
-}
-
-/**
-   \brief Get PseudoDC vertex id of selected line
-
-   Set bounding box for vertices of line.
-
-   \param[in] x,y coordinates of click
-   \param[in] thresh threshold value
-
-   \return id of center, left and right vertex
-
-   \return 0 no line found
-   \return -1 on error
-*/
-std::vector<int> DisplayDriver::GetSelectedVertex(double x, double y, double thresh)
-{
-    int startId;
-    int line, type;
-    int Gid, DCid;
-    double vx, vy, vz;      // vertex screen coordinates
-
-    double dist, minDist;
-
-    std::vector<int> returnId;
-
-    // only one object can be selected
-    if (selected.size() != 1 || !drawSegments) 
-	return returnId;
-
-    startId = 1;
-    line = selected[0];
-
-    type = Vect_read_line (mapInfo, points, cats, line);
-        
-    // find the closest vertex (x, y)
-    DCid = 1;
-    for(int idx = 0; idx < points->n_points; idx++) {
-	dist = Vect_points_distance(x, y, 0.0,
-				    points->x[idx], points->y[idx], points->z[idx], 0);
-	
-	if (idx == 0) {
-	    minDist = dist;
-	    Gid  = idx;
-	}
-	else {
-	    if (minDist > dist) {
-		minDist = dist;
-		Gid = idx;
-	    }
-	}
-
-	Cell2Pixel(points->x[idx], points->y[idx], points->z[idx],
-		   &vx, &vy, &vz);
-	wxRect rect (wxPoint ((int) vx, (int) vy), wxPoint ((int) vx, (int) vy));
-	dc->SetIdBounds(DCid, rect);
-	DCid+=2;
-    }	
-
-    if (minDist > thresh)
-	return returnId;
-
-    // desc = &(ids[line]);
-
-    // translate id
-    DCid = Gid * 2 + 1;
-
-    // add selected vertex
-    returnId.push_back(DCid);
-    // left vertex
-    if (DCid == startId) {
-	returnId.push_back(-1);
-    }
-    else {
-	returnId.push_back(DCid - 2);
-    }
-
-    // right vertex
-    if (DCid == (points->n_points - 1) * 2 + startId) {
-	returnId.push_back(-1);
-    }
-    else {
-	returnId.push_back(DCid + 2);
-    }
-
-    return returnId;
-}
-
-/**
-   \brief Reset topology structure.
-
-   \return
-*/
-void DisplayDriver::ResetTopology()
-{
-    topology.highlight = 0;
-    
-    topology.point = 0;
-    topology.line = 0;
-    
-    topology.boundaryNo = 0;
-    topology.boundaryOne = 0;
-    topology.boundaryTwo = 0;
-    
-    topology.centroidIn = 0;
-    topology.centroidOut = 0;
-    topology.centroidDup = 0;
-    
-    topology.nodeOne = 0;
-    topology.nodeTwo = 0;
-    
-    topology.vertex = 0;
-
-    return;
-}

Copied: grass/trunk/gui/wxpython/vdigit/driver.cpp (from rev 29600, grass/trunk/gui/wxpython/display_driver/driver.cpp)
===================================================================
--- grass/trunk/gui/wxpython/vdigit/driver.cpp	                        (rev 0)
+++ grass/trunk/gui/wxpython/vdigit/driver.cpp	2008-01-08 11:48:03 UTC (rev 29601)
@@ -0,0 +1,1078 @@
+/**
+   \file driver.cpp
+   
+   \brief Experimental C++ wxWidgets display driver
+
+   This driver is designed for wxPython GRASS GUI (digitization tool).
+   Draw vector map layer to PseudoDC.
+
+   This program is free software under the GNU General Public
+   License (>=v2). Read the file COPYING that comes with GRASS
+   for details.
+
+   \author (C) by the GRASS Development Team
+   Martin Landa <landa.martin gmail.com>
+
+   \date 2007-2008 
+*/
+
+#include "driver.h"
+
+/**
+   \brief Initialize driver
+
+   Allocate given structures.
+   
+   \param[in,out] PseudoDC device where to draw vector objects
+   
+   \return
+*/
+DisplayDriver::DisplayDriver(void *device)
+{
+    G_gisinit(""); /* GRASS functions */
+
+    mapInfo = NULL;
+
+    dc = (wxPseudoDC *) device;
+
+    points       = Vect_new_line_struct();
+    pointsScreen = new wxList();
+    cats         = Vect_new_cats_struct();
+
+    drawSegments = false;
+}
+
+/**
+   \brief Destroy driver
+
+   Close the map, deallocate given structures.
+
+   \param
+
+   \return
+*/
+DisplayDriver::~DisplayDriver()
+{
+    if (mapInfo)
+	CloseMap();
+
+    Vect_destroy_line_struct(points);
+    delete pointsScreen;
+    Vect_destroy_cats_struct(cats);
+}
+
+/**
+   \brief Set device for drawing
+   
+   \param[in,out] PseudoDC device where to draw vector objects
+
+   \return
+*/
+void DisplayDriver::SetDevice(void *device)
+{
+    dc = (wxPseudoDC *) device;
+
+    return;
+}
+
+/**
+   \brief Draw content of the vector map to device
+   
+   \return number of lines which were drawn
+   \return -1 on error
+ */
+int DisplayDriver::DrawMap(bool force)
+{
+    if (!mapInfo || !dc)
+	return -1;
+
+    int nlines;
+    BOUND_BOX mapBox;
+    struct ilist *listLines;
+
+    // ids.clear();
+    listLines = Vect_new_list();
+
+    ResetTopology();
+
+    /* nlines = Vect_get_num_lines(mapInfo); */
+
+    //Vect_build_partial(mapInfo, GV_BUILD_NONE, stderr);
+    //Vect_build(mapInfo, stderr);
+
+    Vect_get_map_box(mapInfo, &mapBox);
+
+    // draw lines inside of current display region
+    nlines = Vect_select_lines_by_box(mapInfo, &(region.box),
+     				      GV_POINTS | GV_LINES, // fixme
+				      listLines);
+    /*
+    nlines = Vect_select_lines_by_box(mapInfo, &mapBox,
+				      GV_POINTS | GV_LINES, // fixme
+ 				      listLines);
+
+    for (int i = 0; i < listLines->n_values; i++) {
+	DrawLine(listLines->value[i]);
+    }
+    */
+
+#ifdef DEBUG
+    std::cerr.flags(std::ios_base::fixed);
+    std::cerr << "region: W=" << region.box.W
+	      << "; E=" << region.box.E
+	      << "; S=" << region.box.S
+	      << "; N=" << region.box.N << std::endl;
+
+    std::cerr << "-> nlines=" << nlines << std::endl;
+#endif
+
+    bool inBox;
+    dc->BeginDrawing();
+    for (int i = 0; i < listLines->n_values; i++) {
+	DrawLine(listLines->value[i]);
+    }
+    dc->EndDrawing();
+
+#ifdef DEBUG
+    PrintIds();
+#endif
+
+    Vect_destroy_list(listLines);
+
+    return listLines->n_values;
+}	
+
+/**
+   \brief Draw selected vector objects to the device
+ 
+   \param[in] line id
+   \return 1 on success
+   \return -1 on failure (vector object is dead, etc.)
+*/
+int DisplayDriver::DrawLine(int line)
+{
+    if (!dc || !Vect_line_alive (mapInfo, line))
+	return -1;
+
+    int dcId;    // 0 | 1 | segment id
+    int type;    // line type
+    double x, y, z; // screen coordinates
+    bool draw;   // draw object ?
+
+    wxPen *pen;
+
+    // read line
+    type = Vect_read_line (mapInfo, points, cats, line);
+
+    // add ids
+    // -> node1, line1, vertex1, line2, ..., node2
+    // struct lineDesc desc = {points->n_points, dcId};
+    // ids[line] = desc;
+    // update id for next line
+    // dcId += points->n_points * 2 - 1;
+
+    if (IsSelected(line)) { // line selected ?
+	pen = new wxPen(settings.highlight, settings.lineWidth, wxSOLID);
+	draw = true;
+	dcId = 1;
+	topology.highlight++;
+    }
+    else {
+	dcId = 0;
+	if (type & GV_LINES) {
+	    switch (type) {
+	    case GV_LINE:
+		pen = new wxPen(settings.line.color, settings.lineWidth, wxSOLID);
+		topology.line++;
+		draw = settings.line.enabled;
+		break;
+	    case GV_BOUNDARY:
+		int left, right;
+		Vect_get_line_areas(mapInfo, line,
+				    &left, &right);
+		if (left == 0 && right == 0) {
+		    pen = new wxPen(settings.boundaryNo.color, settings.lineWidth, wxSOLID);
+		    topology.boundaryNo++;
+		    draw = settings.boundaryNo.enabled;
+		}
+		else if (left > 0 && right > 0) {
+		    pen = new wxPen(settings.boundaryTwo.color, settings.lineWidth, wxSOLID);
+		    topology.boundaryTwo++;
+		    draw = settings.boundaryTwo.enabled;
+		}
+		else {
+		    pen = new wxPen(settings.boundaryOne.color, settings.lineWidth, wxSOLID);
+		    topology.boundaryOne++;
+		    draw = settings.boundaryOne.enabled;
+		}
+		break;
+	    default:
+		draw = false;
+		break;
+	    }
+	}
+	else if (type & GV_POINTS) {
+	    if (type == GV_POINT && settings.point.enabled) {
+		pen = new wxPen(settings.point.color, settings.lineWidth, wxSOLID);
+		topology.point++;
+		draw = settings.point.enabled;
+	    }
+	    else if (type == GV_CENTROID) {
+		int cret = Vect_get_centroid_area(mapInfo, line);
+		if (cret > 0) { // -> area
+		    draw = settings.centroidIn.enabled;
+		    pen = new wxPen(settings.centroidIn.color, settings.lineWidth, wxSOLID);
+		    topology.centroidIn++;
+		}
+		else if (cret == 0) {
+		    draw = settings.centroidOut.enabled;
+		    pen = new wxPen(settings.centroidOut.color, settings.lineWidth, wxSOLID);
+		    topology.centroidOut++;
+		}
+		else {
+		    draw = settings.centroidDup.enabled;
+		    pen = new wxPen(settings.centroidDup.color, settings.lineWidth, wxSOLID);
+		    topology.centroidDup++;
+		}
+	    }
+	}
+    }
+    
+    // clear screen points & convert EN -> xy
+    pointsScreen->Clear();
+    for (int i = 0; i < points->n_points; i++) {
+	Cell2Pixel(points->x[i], points->y[i], points->z[i],
+		   &x, &y, &z);
+	pointsScreen->Append((wxObject*) new wxPoint((int) x, (int) y)); /* TODO: 3D */
+    }
+    
+    dc->SetId(dcId); /* 0 | 1 (selected) */
+    dc->SetPen(*pen);
+
+    if (draw) {
+	if (type & GV_POINTS) {
+	    DrawCross(line, (const wxPoint *) pointsScreen->GetFirst()->GetData());
+	}
+	else {
+	    // long int startId = ids[line].startId + 1;
+	    if (dcId > 0 && drawSegments) {
+		dcId = 2; // first segment
+		for (int i = 0; i < pointsScreen->GetCount() - 1; dcId += 2) {
+		wxPoint *point_beg = (wxPoint *) pointsScreen->Item(i)->GetData();
+		wxPoint *point_end = (wxPoint *) pointsScreen->Item(++i)->GetData();
+
+		// set bounds for line
+		// wxRect rect (*point_beg, *point_end);
+		// dc->SetIdBounds(startId, rect);
+		
+		dc->SetId(dcId); // set unique id & set bbox for each segment
+		dc->SetPen(*pen);
+		wxRect rect (*point_beg, *point_end);
+		dc->SetIdBounds(dcId, rect);
+		dc->DrawLine(point_beg->x, point_beg->y,
+			     point_end->x, point_end->y);
+		}
+	    }
+	    else {
+		wxPoint points[pointsScreen->GetCount()];
+		for (int i = 0; i < pointsScreen->GetCount(); i++) {
+		    wxPoint *point_beg = (wxPoint *) pointsScreen->Item(i)->GetData();
+		    points[i] = *point_beg;
+		}
+		dc->DrawLines(pointsScreen->GetCount(), points);
+	    }
+	}
+    }
+
+    if (type & GV_LINES) {
+	DrawLineVerteces(line); // draw vertices
+	DrawLineNodes(line);    // draw nodes
+    }
+
+    delete pen;
+
+    return 1;
+}
+
+/**
+   \brief Draw line verteces to the device
+ 
+   Except of first and last vertex, see DrawLineNodes().
+
+   \param line id
+
+   \return number of verteces which were drawn
+   \return -1 if drawing vertices is disabled
+*/
+int DisplayDriver::DrawLineVerteces(int line)
+{
+    int dcId;
+    wxPoint *point;
+    wxPen *pen;
+
+    if (!IsSelected(line) && !settings.vertex.enabled)
+	return -1;
+
+    // determine color
+    if (!IsSelected(line)) {
+	pen = new wxPen(settings.vertex.color, settings.lineWidth, wxSOLID);
+	dcId = 0;
+    }
+    else {
+	pen = new wxPen(settings.highlight, settings.lineWidth, wxSOLID);
+	if (drawSegments) {
+	    dcId = 3; // first vertex
+	}
+	else {
+	    dcId = 1;
+	}
+    }
+
+    dc->SetId(dcId); /* 0 | 1 (selected) */
+    dc->SetPen(*pen);
+
+    for (int i = 1; i < pointsScreen->GetCount() - 1; i++, dcId += 2) {
+	point = (wxPoint*) pointsScreen->Item(i)->GetData();
+
+	if (IsSelected(line) && drawSegments) {
+	    dc->SetId(dcId);
+	    dc->SetPen(*pen);
+	    wxRect rect (*point, *point);
+	    dc->SetIdBounds(dcId, rect);
+	}
+	
+	if (settings.vertex.enabled) {
+	    DrawCross(line, (const wxPoint*) pointsScreen->Item(i)->GetData());
+	    topology.vertex++;
+	}
+    }
+
+    delete pen;
+
+    return pointsScreen->GetCount() - 2;
+}
+
+/**
+   \brief Draw line nodes to the device
+ 
+   \param line id
+
+   \return 1
+   \return -1 if no nodes were drawn
+*/
+int DisplayDriver::DrawLineNodes(int line)
+{
+    int dcId;
+    int node;
+    double east, north, depth;
+    double x, y, z;
+    int nodes [2];
+    bool draw;
+
+    wxPen *pen;
+
+    // draw nodes??
+    if (!settings.nodeOne.enabled && !settings.nodeTwo.enabled)
+	return -1;
+
+    // get nodes
+    Vect_get_line_nodes(mapInfo, line, &(nodes[0]), &(nodes[1]));
+        
+    for (int i = 0; i < sizeof(nodes) / sizeof(int); i++) {
+	node = nodes[i];
+	// get coordinates
+	Vect_get_node_coor(mapInfo, node,
+			   &east, &north, &depth);
+
+	// convert EN->xy
+	Cell2Pixel(east, north, depth,
+		   &x, &y, &z);
+
+	// determine color
+	if (IsSelected(line)) {
+	    pen = new wxPen(settings.highlight, settings.lineWidth, wxSOLID);
+	    draw = true;
+	    if (!drawSegments) {
+		dcId = 1;
+	    }
+	    else {
+		// node1, line1, vertex1, line2, vertex2, ..., node2
+		if (i == 0) // first node
+		    dcId = 1; 
+		else // last node
+		    dcId = 2 * points->n_points - 1;
+	    }
+	}
+	else {
+	    dcId = 0;
+	    if (Vect_get_node_n_lines(mapInfo, node) == 1) {
+		pen = new wxPen(settings.nodeOne.color, settings.lineWidth, wxSOLID);
+		topology.nodeOne++;
+		draw = settings.nodeOne.enabled;
+	    }
+	    else {
+		pen = new wxPen(settings.nodeTwo.color, settings.lineWidth, wxSOLID);
+		topology.nodeTwo++;
+		draw = settings.nodeTwo.enabled;
+	    }
+	}
+	
+	wxPoint point((int) x, (int) y);
+	if (IsSelected(line) && drawSegments) {
+	    wxRect rect (point, point);
+	    dc->SetIdBounds(dcId, rect);
+	}
+
+	// draw node if needed
+	if (draw) {
+	    dc->SetId(dcId);
+	    dc->SetPen(*pen);
+	    DrawCross(line, &point);
+	}
+    }
+    
+    delete pen;
+
+    return 1;
+}
+
+
+/*
+  \brief Close vector map layer
+  
+  \param
+
+  \return
+*/
+void DisplayDriver::CloseMap()
+{
+    if (mapInfo) {
+	if (mapInfo->mode == GV_MODE_RW) {
+	    Vect_build(mapInfo, NULL);
+	}
+	Vect_close(mapInfo);
+	G_free ((void *) mapInfo);
+	mapInfo = NULL;
+    }
+    
+    return;
+}
+
+/**
+   \brief Open vector map layer
+ 
+   \param[in] mapname name of vector map
+   \param[in] mapset name of mapset where the vector map layer is stored
+   
+   \return topo level
+   \return -1 on error
+*/
+int DisplayDriver::OpenMap(const char* mapname, const char *mapset, bool update)
+{
+    int ret;
+
+    if (!mapInfo)
+	mapInfo = (struct Map_info *) G_malloc (sizeof (struct Map_info));
+
+    // define open level (level 2: topology)
+    Vect_set_open_level(2);
+
+    // open existing map
+    if (!update) {
+	ret = Vect_open_old(mapInfo, (char*) mapname, (char *) mapset);
+    }
+    else {
+	ret = Vect_open_update(mapInfo, (char*) mapname, (char *) mapset);
+    }
+
+    return ret;
+}
+
+/**
+   \brief Reload vector map layer
+
+   Close and open again. Needed for modification using v.edit.
+
+   TODO: Get rid of that...
+
+   \param
+   
+   \return
+*/
+void DisplayDriver::ReloadMap()
+{
+    // char* name   = G_store(Vect_get_map_name(mapInfo)); ???
+    char* name   = G_store(mapInfo->name);
+    char* mapset = G_store(Vect_get_mapset(mapInfo));
+
+    Vect_close(mapInfo);
+    mapInfo = NULL;
+
+    OpenMap(name, mapset, false); // used only for v.edit
+    //Vect_build_partial(mapInfo, GV_BUILD_NONE, stderr);
+    //Vect_build(mapInfo, stderr);
+
+    return;
+}
+
+/*
+  \brief Conversion from geographic coordinates (east, north)
+  to screen (x, y)
+  
+  TODO: 3D stuff...
+
+  \param[in] east,north,depth geographical coordinates
+  \param[out] x, y, z screen coordinates
+  
+  \return 
+*/
+void DisplayDriver::Cell2Pixel(double east, double north, double depth,
+			       double *x, double *y, double *z)
+{
+    double n, w;
+    /*
+    *x = int((east  - region.map_west) / region.map_res);
+    *y = int((region.map_north - north) / region.map_res);
+    */
+    w = region.center_easting  - (region.map_width / 2)  * region.map_res;
+    n = region.center_northing + (region.map_height / 2) * region.map_res;
+
+    /*
+    *x = int((east  - w) / region.map_res);
+    *y = int((n - north) / region.map_res);
+    */
+    *x = (east  - w) / region.map_res;
+    *y = (n - north) / region.map_res;
+
+    *z = 0;
+
+    return;
+}
+
+/**
+   \brief Set geographical region
+ 
+   Region must be upgraded because of Cell2Pixel().
+   
+   \param[in] north,south,east,west,ns_res,ew_res region settings
+ 
+   \return
+*/
+void DisplayDriver::SetRegion(double north, double south, double east, double west,
+			      double ns_res, double ew_res,
+			      double center_easting, double center_northing,
+			      double map_width, double map_height)
+{
+    region.box.N  = north;
+    region.box.S  = south;
+    region.box.E  = east;
+    region.box.W  = west;
+    region.box.T  = PORT_DOUBLE_MAX;
+    region.box.B  = -PORT_DOUBLE_MAX;
+    region.ns_res = ns_res;
+    region.ew_res = ew_res;
+
+    region.center_easting = center_easting;
+    region.center_northing = center_northing;
+
+    region.map_width  = map_width;
+    region.map_height = map_height;
+
+#ifdef DEBUG
+    std::cerr << "region: n=" << north
+	      << "; s=" << south
+	      << "; e=" << east
+	      << "; w=" << west
+	      << "; ns_res=" << ns_res
+	      << "; ew_res=" << ew_res
+	      << "; center_easting=" << center_easting
+	      << "; center_northing=" << center_northing
+	      << "; map_width=" << map_width
+	      << "; map_height=" << map_height
+	      << std::endl;
+#endif
+
+    // calculate real region
+    region.map_res = (region.ew_res > region.ns_res) ? region.ew_res : region.ns_res;
+
+    region.map_west  = region.center_easting - (region.map_width / 2.) * region.map_res;
+    region.map_north = region.center_northing + (region.map_height / 2.) * region.map_res;
+
+    return;
+}
+
+/**
+   \brief Draw cross symbol of given size to device content
+   
+   Used for points, nodes, vertices
+
+   \param[in] point coordinates of center
+   \param[in] size size of the cross symbol
+   
+   \return 1 on success
+   \return -1 on failure
+*/
+int DisplayDriver::DrawCross(int line, const wxPoint* point, int size)
+{
+    if (!dc || !point)
+	return -1;
+
+    dc->DrawLine(point->x - size, point->y, point->x + size, point->y);
+    dc->DrawLine(point->x, point->y - size, point->x, point->y + size);
+    return 1;
+}
+
+/*
+  \brief Set settings for displaying vector feature
+ 
+  E.g. line width, color, ...
+  
+  \param[in] lineWidth,... settgings
+  
+  \return 
+*/
+void DisplayDriver::UpdateSettings(unsigned long highlight,
+				   bool ePoint,       unsigned long cPoint, /* enabled, color */
+				   bool eLine,        unsigned long cLine,
+				   bool eBoundaryNo,  unsigned long cBoundaryNo,
+				   bool eBoundaryOne, unsigned long cBoundaryOne,
+				   bool eBoundaryTwo, unsigned long cBoundaryTwo,
+				   bool eCentroidIn,  unsigned long cCentroidIn,
+				   bool eCentroidOut, unsigned long cCentroidOut,
+				   bool eCentroidDup, unsigned long cCentroidDup,
+				   bool eNodeOne,     unsigned long cNodeOne,
+				   bool eNodeTwo,     unsigned long cNodeTwo,
+				   bool eVertex,      unsigned long cVertex,
+				   int lineWidth,
+				   double threshold)
+{
+    settings.highlight.Set(highlight);
+
+    settings.point.enabled = ePoint;
+    settings.point.color.Set(cPoint);
+
+    settings.line.enabled = eLine;
+    settings.line.color.Set(cLine);
+
+    settings.boundaryNo.enabled = eBoundaryNo;
+    settings.boundaryNo.color.Set(cBoundaryNo);
+    settings.boundaryOne.enabled = eBoundaryOne;
+    settings.boundaryOne.color.Set(cBoundaryOne);
+    settings.boundaryTwo.enabled = eBoundaryTwo;
+    settings.boundaryTwo.color.Set(cBoundaryTwo);
+
+
+    settings.centroidIn.enabled = eCentroidIn;
+    settings.centroidIn.color.Set(cCentroidIn);
+    settings.centroidOut.enabled = eCentroidOut;
+    settings.centroidOut.color.Set(cCentroidOut);
+    settings.centroidDup.enabled = eCentroidDup;
+    settings.centroidDup.color.Set(cCentroidDup);
+
+    settings.nodeOne.enabled = eNodeOne;
+    settings.nodeOne.color.Set(cNodeOne);
+    settings.nodeTwo.enabled = eNodeTwo;
+    settings.nodeTwo.color.Set(cNodeTwo);
+
+    settings.vertex.enabled = eVertex;
+    settings.vertex.color.Set(cVertex);
+
+    settings.lineWidth = lineWidth;
+    settings.threshold = threshold;    
+}
+
+/**
+   \brief Prints gId: dcIds
+
+   Useful for debugging purposes.
+
+   \param
+
+   \return
+*/
+void DisplayDriver::PrintIds()
+{
+    /*
+      for (ids_map::const_iterator i = ids.begin(), e = ids.end();
+      i != e; ++i) {
+      std::cerr << "line=" << i->first << ": "
+      << "npoints=" << i->second.npoints
+      << " startId=" << i->second.startId
+      << std::endl;
+      }
+    */
+
+    std::cerr << "topology.highlight: " << topology.highlight << std::endl;
+
+    std::cerr << "topology.point: " << topology.point << std::endl;
+    std::cerr << "topology.line: " << topology.line << std::endl;
+
+    std::cerr << "topology.boundaryNo: " << topology.boundaryNo << std::endl;
+    std::cerr << "topology.boundaryOne: " << topology.boundaryOne << std::endl;
+    std::cerr << "topology.boundaryTwo: " << topology.boundaryTwo << std::endl;
+
+    std::cerr << "topology.centroidIn: " << topology.centroidIn << std::endl;
+    std::cerr << "topology.centroidOut: " << topology.centroidOut << std::endl;
+    std::cerr << "topology.centroidDup: " << topology.centroidDup << std::endl;
+
+    std::cerr << "topology.nodeOne: " << topology.nodeOne << std::endl;
+    std::cerr << "topology.nodeTwo: " << topology.nodeTwo << std::endl;
+
+    std::cerr << "topology.vertex: " << topology.vertex << std::endl;
+
+    std::cerr << std::endl << "nobjects: "
+	      << topology.point * 2 + // cross
+      topology.line + 
+      topology.boundaryNo +
+      topology.boundaryOne +
+      topology.boundaryTwo +
+      topology.centroidIn * 2 +
+      topology.centroidOut * 2 +
+      topology.centroidDup * 2 +
+      topology.nodeOne * 2 +
+      topology.nodeTwo * 2 +
+      topology.vertex * 2 << std::endl;
+
+    std::cerr << "selected: ";
+    for (std::vector<int>::const_iterator i = selected.begin(), e = selected.end();
+	 i != e; ++i)
+	std::cerr << *i << " ";
+    std::cerr << std::endl;
+
+    return;
+}
+
+/**
+   \brief Select vector objects by given bounding box
+   
+   If line id is already in the list of selected lines, then it will
+   be excluded from this list.
+
+   \param[in] x1,y1,x2,y2 corners coordinates of bounding box
+
+   \return number of selected features
+   \return -1 on error
+*/
+int DisplayDriver::SelectLinesByBox(double x1, double y1, double x2, double y2)
+{
+    if (!mapInfo)
+	return -1;
+
+    int type, line;
+    double dx, dy;
+
+    struct ilist *list;
+    struct line_pnts *bbox;
+
+    type = -1; // all types
+
+    list = Vect_new_list();
+    bbox = Vect_new_line_struct();
+
+    dx = std::fabs(x2 - x1);
+    dy = std::fabs(y2 - y1);
+        
+    Vect_append_point(bbox, x1, y1, -PORT_DOUBLE_MAX);
+    Vect_append_point(bbox, x2, y1,  PORT_DOUBLE_MAX);
+    Vect_append_point(bbox, x2, y2, -PORT_DOUBLE_MAX);
+    Vect_append_point(bbox, x1, y2,  PORT_DOUBLE_MAX);
+    Vect_append_point(bbox, x1, y1, -PORT_DOUBLE_MAX);
+        
+    Vect_select_lines_by_polygon(mapInfo, bbox,
+				 0, NULL,
+				 type, list);
+	
+    for (int i = 0; i < list->n_values; i++) {
+	line = list->value[i];
+	if (!IsSelected(line)) {
+	    selected.push_back(line);
+	}
+	else {
+	    selected.erase(GetSelectedIter(line));
+	}
+    }
+
+    // remove all duplicate ids
+    sort(selected.begin(), selected.end());
+    selected.erase(unique(selected.begin(), selected.end()), selected.end());
+
+    Vect_destroy_line_struct(bbox);
+    Vect_destroy_list(list);
+
+    return selected.size();
+}
+
+/**
+   \brief Select vector feature by given point in given
+   threshold
+   
+   Only one vector object can be selected. Bounding boxes of
+   all segments are stores.
+
+   \param[in] x,y point of searching
+   \param[in] thresh threshold value where to search
+   \param[in] onlyType select vector object of given type
+
+   \return point on line if line found
+*/
+std::vector<double> DisplayDriver::SelectLineByPoint(double x, double y, double thresh,
+						     int type)
+{
+    long int line;
+    int ftype;
+    double px, py, pz;
+
+    std::vector<double> p;
+
+    if (type == -1) {
+	ftype = GV_POINTS | GV_LINES;
+    }
+    else if (type == 0) {
+	ftype = GV_POINTS;
+    }
+    else if (type == 1) {
+	ftype = GV_LINES;
+    }
+
+    line = Vect_find_line(mapInfo, x, y, 0.0,
+			  ftype, thresh, 0, 0);
+
+    if (line > 0) {
+	selected.push_back(line);
+	type = Vect_read_line (mapInfo, points, cats, line);
+	Vect_line_distance (points, x, y, 0.0, WITHOUT_Z,
+			    &px, &py, &pz,
+			    NULL, NULL, NULL);
+	p.push_back(px);
+	p.push_back(py);
+    }
+
+    drawSegments = true;
+
+    return p;
+}
+
+/**
+   \brief Is vector object selected?
+   
+   \param[in] line id
+
+   \return true if vector object is selected
+   \return false if vector object is not selected
+*/
+bool DisplayDriver::IsSelected(int line)
+{
+    if (GetSelectedIter(line) != selected.end())
+	return true;
+
+    return false;
+}
+
+/**
+   \brief Is vector object selected?
+   
+   \param[in] line id
+
+   \return item iterator
+   \return selected.end() if object is not selected
+*/
+std::vector<int>::iterator DisplayDriver::GetSelectedIter(int line)
+{
+    for(std::vector<int>::iterator i = selected.begin(), e = selected.end();
+	i != e; ++i) {
+	if (line == *i)
+	    return i;
+    }
+
+    return selected.end();
+}
+
+/**
+   \brief Get ids of selected objects
+
+   \param[in] grassId if true return GRASS line ids
+   if false return PseudoDC ids
+   
+   \return list of ids of selected vector objects
+*/
+std::vector<int> DisplayDriver::GetSelected(bool grassId)
+{
+    if (grassId)
+	return selected;
+
+    std::vector<int> dc_ids;
+    long int line;
+
+    if (!drawSegments) {
+	dc_ids.push_back(1);
+    }
+    else {
+	int npoints;
+	Vect_read_line(mapInfo, points, NULL, selected[0]);
+	npoints = points->n_points;
+	for (int i = 1; i < 2 * npoints; i++) {
+	  dc_ids.push_back(i);
+	}
+    }
+
+    /*
+    for(std::vector<int>::const_iterator i = selected.begin(), e = selected.end();
+	i != e; ++i) {
+	line = *i;
+	ids_map::const_iterator ii = ids.find(line);
+	if (ii != ids.end()) { // line found
+	    long int endId = ii->second.npoints * 2 - 1 + ii->second.startId;
+	    int type, i;
+	    int vx, vy, vz;
+	    type = Vect_read_line (mapInfo, points, cats, line);
+	    i = 0;
+ 	    for (long int id = ii->second.startId; id < endId; id++) {
+		dc_ids.push_back(id);
+                // set bounding boxes for all selected objects (only nodes)
+		if (id % 2) {
+		    Cell2Pixel(points->x[i], points->y[i], points->z[i],
+			       &vx, &vy, &vz);
+		    wxRect rect (wxPoint (vx, vy), wxPoint (vx, vy));
+		    dc->SetIdBounds(id, rect);
+
+		    i++;
+		}
+
+	    }
+	}
+    }
+    */
+
+    return dc_ids;
+}
+
+/**
+   \brief Set selected vector objects
+   
+   \param[in] list of GRASS ids to be set
+
+   \return 1
+*/
+int DisplayDriver::SetSelected(std::vector<int> id)
+{
+    selected = id;
+
+    if (selected.size() <= 0)
+	drawSegments = false;
+
+    return 1;
+}
+
+/**
+   \brief Get PseudoDC vertex id of selected line
+
+   Set bounding box for vertices of line.
+
+   \param[in] x,y coordinates of click
+   \param[in] thresh threshold value
+
+   \return id of center, left and right vertex
+
+   \return 0 no line found
+   \return -1 on error
+*/
+std::vector<int> DisplayDriver::GetSelectedVertex(double x, double y, double thresh)
+{
+    int startId;
+    int line, type;
+    int Gid, DCid;
+    double vx, vy, vz;      // vertex screen coordinates
+
+    double dist, minDist;
+
+    std::vector<int> returnId;
+
+    // only one object can be selected
+    if (selected.size() != 1 || !drawSegments) 
+	return returnId;
+
+    startId = 1;
+    line = selected[0];
+
+    type = Vect_read_line (mapInfo, points, cats, line);
+        
+    // find the closest vertex (x, y)
+    DCid = 1;
+    for(int idx = 0; idx < points->n_points; idx++) {
+	dist = Vect_points_distance(x, y, 0.0,
+				    points->x[idx], points->y[idx], points->z[idx], 0);
+	
+	if (idx == 0) {
+	    minDist = dist;
+	    Gid  = idx;
+	}
+	else {
+	    if (minDist > dist) {
+		minDist = dist;
+		Gid = idx;
+	    }
+	}
+
+	Cell2Pixel(points->x[idx], points->y[idx], points->z[idx],
+		   &vx, &vy, &vz);
+	wxRect rect (wxPoint ((int) vx, (int) vy), wxPoint ((int) vx, (int) vy));
+	dc->SetIdBounds(DCid, rect);
+	DCid+=2;
+    }	
+
+    if (minDist > thresh)
+	return returnId;
+
+    // desc = &(ids[line]);
+
+    // translate id
+    DCid = Gid * 2 + 1;
+
+    // add selected vertex
+    returnId.push_back(DCid);
+    // left vertex
+    if (DCid == startId) {
+	returnId.push_back(-1);
+    }
+    else {
+	returnId.push_back(DCid - 2);
+    }
+
+    // right vertex
+    if (DCid == (points->n_points - 1) * 2 + startId) {
+	returnId.push_back(-1);
+    }
+    else {
+	returnId.push_back(DCid + 2);
+    }
+
+    return returnId;
+}
+
+/**
+   \brief Reset topology structure.
+
+   \return
+*/
+void DisplayDriver::ResetTopology()
+{
+    topology.highlight = 0;
+    
+    topology.point = 0;
+    topology.line = 0;
+    
+    topology.boundaryNo = 0;
+    topology.boundaryOne = 0;
+    topology.boundaryTwo = 0;
+    
+    topology.centroidIn = 0;
+    topology.centroidOut = 0;
+    topology.centroidDup = 0;
+    
+    topology.nodeOne = 0;
+    topology.nodeTwo = 0;
+    
+    topology.vertex = 0;
+
+    return;
+}

Deleted: grass/trunk/gui/wxpython/vdigit/driver.h
===================================================================
--- grass/trunk/gui/wxpython/display_driver/driver.h	2008-01-07 12:38:19 UTC (rev 29593)
+++ grass/trunk/gui/wxpython/vdigit/driver.h	2008-01-08 11:48:03 UTC (rev 29601)
@@ -1,190 +0,0 @@
-#include <iostream> // debug
-#include <vector>
-//#include <map>
-#include <cmath>
-
-// For compilers that support precompilation, includes "wx.h".
-#include <wx/wxprec.h>
-
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-
-#ifndef WX_PRECOMP
-// Include your minimal set of headers here, or wx.h
-#include <wx/wx.h>
-#endif
-
-#include <wx/dc.h>
-#include <wx/list.h>
-
-#include <Python.h>
-#include <wx/wxPython/pseudodc.h>
-//#include "pseudodc.h"
-
-extern "C" {
-#include <grass/gis.h>
-#include <grass/Vect.h>
-}
-
-// #define DEBUG
-
-class DisplayDriver
-{
- private:
-    wxPseudoDC *dc;  // device content
-
-    /* disabled due to expensive calling dc->SetId()
-     *
-     * currently all objects are drawn without id
-     *
-     * only selected lines with id '1'
-     *
-     * segments with unique id (starting with '1')
-     * are drawn only when line was selected using SelectLineByPoint()
-     */
-    /*
-    struct lineDesc {
-	int      npoints;
-	long int startId;
-    };
-    
-    typedef std::map<int, lineDesc> ids_map;
-    
-    ids_map ids; // gId : {dcIds, ...}
-    */
-
-    std::vector<int> selected; // list of selected features (gId)
-    bool drawSegments;         // draw segments of selected line
-
-    struct Map_info  *mapInfo;
-    struct line_pnts *points;       // east, north, depth
-    wxList           *pointsScreen; // x, y, z
-    struct line_cats *cats;
-    
-    struct _region {
-	// GRASS region section
-	BOUND_BOX box; // W,E,N,S,T,B
-	double ns_res;
-	double ew_res;
-	double center_easting;
-	double center_northing;
-
-	// map window section
-	double map_width;  // px
-	double map_height;
-	double map_west;
-	double map_north;
-	double map_res;
-    } region;
-
-    struct symbol {
-	bool enabled;
-	wxColor color;
-    };
-
-    struct _settings {
-	wxColor highlight;
-
-	symbol point;
-	symbol line;
-	
-	symbol boundaryNo;
-	symbol boundaryOne;
-	symbol boundaryTwo;
-
-	symbol centroidIn;
-	symbol centroidOut;
-	symbol centroidDup;
-	
-	symbol nodeOne;
-	symbol nodeTwo;
-
-	symbol vertex;
-
-	int lineWidth; // screen units 
-
-    } settings;
-
-    struct _topology {
-	long int highlight;
-
-	long int point;
-	long int line;
-
-	long int boundaryNo;
-	long int boundaryOne;
-	long int boundaryTwo;
-
-	long int centroidIn;
-	long int centroidOut;
-	long int centroidDup;
-
-	long int nodeOne;
-	long int nodeTwo;
-
-	long int vertex;
-    } topology;
-
-    void Cell2Pixel (double east, double north, double depth,
-		     double *x, double *y, double *z);
-    
-    int DrawCross(int line, const wxPoint *point, int size=5);
-
-    int DrawLine(int line);
-    int DrawLineVerteces(int line);
-    int DrawLineNodes(int line);
-
-    /* debug */
-    void PrintIds();
-
-    /* select feature */
-    bool IsSelected(int line);
-    std::vector<int>::iterator GetSelectedIter(int line);
-
-    void ResetTopology();
-
- public:
-    /* constructor */
-    DisplayDriver(void *device);
-    /* destructor */
-    ~DisplayDriver();
-
-    /* display */
-    int DrawMap(bool force);
-
-    /* select */
-    int SelectLinesByBox(double x1, double y1, double x2, double y2);
-    std::vector<double> SelectLineByPoint(double x, double y, double thresh,
-					  int type);
-
-    std::vector<int> GetSelected(bool grassId);
-    int SetSelected(std::vector<int> id);
-    std::vector<int> GetSelectedVertex(double x, double y, double thresh);
-
-    /* general */
-    void CloseMap();
-    void OpenMap(const char *mapname, const char *mapset);
-    void ReloadMap();
-    void SetDevice(void *device);
-
-    /* set */
-    void SetRegion(double north, double south, double east, double west,
-		   double ns_res, double ew_res,
-		   double center_easting, double center_northing,
-		   double map_width, double map_height);
-
-    void SetSettings(unsigned long highlight,
-		     bool ePoint,       unsigned long cPoint, /* enabled, color */
-		     bool eLine,        unsigned long cLine,
-		     bool eBoundaryNo,  unsigned long cBoundaryNo,
-		     bool eBoundaryOne, unsigned long cBoundaryOne,
-		     bool eBoundaryTwo, unsigned long cBoundaryTwo,
-		     bool eCentroidIn,  unsigned long cCentroidIn,
-		     bool eCentroidOut, unsigned long cCentroidOut,
-		     bool eCentroidDup, unsigned long cCentroidDup,
-		     bool eNodeOne,     unsigned long cNodeOne,
-		     bool eNodeTwo,     unsigned long cNodeTwo,
-		     bool eVertex,      unsigned long cVertex,
-		     int lineWidth);
-};

Copied: grass/trunk/gui/wxpython/vdigit/driver.h (from rev 29600, grass/trunk/gui/wxpython/display_driver/driver.h)
===================================================================
--- grass/trunk/gui/wxpython/vdigit/driver.h	                        (rev 0)
+++ grass/trunk/gui/wxpython/vdigit/driver.h	2008-01-08 11:48:03 UTC (rev 29601)
@@ -0,0 +1,196 @@
+#ifndef __DRIVER_H__
+#define __DRIVER_H__
+
+#include <iostream> // debug
+#include <vector>
+#include <cmath>
+
+// For compilers that support precompilation, includes "wx.h".
+#include <wx/wxprec.h>
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+// Include your minimal set of headers here, or wx.h
+#include <wx/wx.h>
+#endif
+
+#include <wx/dc.h>
+#include <wx/list.h>
+
+#include <Python.h>
+#include <wx/wxPython/pseudodc.h>
+
+extern "C" {
+#include <grass/gis.h>
+#include <grass/Vect.h>
+}
+
+// #define DEBUG
+
+class DisplayDriver
+{
+private:
+    friend class Digit;
+    wxPseudoDC *dc;  // device content
+
+    /* disabled due to expensive calling dc->SetId()
+     *
+     * currently all objects are drawn without id
+     *
+     * only selected lines with id '1'
+     *
+     * segments with unique id (starting with '1')
+     * are drawn only when line was selected using SelectLineByPoint()
+     */
+    /*
+    struct lineDesc {
+	int      npoints;
+	long int startId;
+    };
+    
+    typedef std::map<int, lineDesc> ids_map;
+    
+    ids_map ids; // gId : {dcIds, ...}
+    */
+
+    std::vector<int> selected; // list of selected features (gId)
+    bool drawSegments;         // draw segments of selected line
+
+    struct Map_info  *mapInfo;
+    struct line_pnts *points;       // east, north, depth
+    wxList           *pointsScreen; // x, y, z
+    struct line_cats *cats;
+    
+    struct _region {
+	// GRASS region section
+	BOUND_BOX box; // W,E,N,S,T,B
+	double ns_res;
+	double ew_res;
+	double center_easting;
+	double center_northing;
+
+	// map window section
+	double map_width;  // px
+	double map_height;
+	double map_west;
+	double map_north;
+	double map_res;
+    } region;
+
+    struct symbol {
+	bool enabled;
+	wxColor color;
+    };
+
+    struct _settings {
+	wxColor highlight;
+
+	symbol point;
+	symbol line;
+	
+	symbol boundaryNo;
+	symbol boundaryOne;
+	symbol boundaryTwo;
+
+	symbol centroidIn;
+	symbol centroidOut;
+	symbol centroidDup;
+	
+	symbol nodeOne;
+	symbol nodeTwo;
+
+	symbol vertex;
+
+	int lineWidth;    // screen units 
+
+	double threshold; // threshold value (map units)
+    } settings;
+
+    struct _topology {
+	long int highlight;
+
+	long int point;
+	long int line;
+
+	long int boundaryNo;
+	long int boundaryOne;
+	long int boundaryTwo;
+
+	long int centroidIn;
+	long int centroidOut;
+	long int centroidDup;
+
+	long int nodeOne;
+	long int nodeTwo;
+
+	long int vertex;
+    } topology;
+
+    void Cell2Pixel (double east, double north, double depth,
+		     double *x, double *y, double *z);
+    
+    int DrawCross(int line, const wxPoint *point, int size=5);
+
+    int DrawLine(int line);
+    int DrawLineVerteces(int line);
+    int DrawLineNodes(int line);
+
+    /* debug */
+    void PrintIds();
+
+    /* select feature */
+    bool IsSelected(int line);
+    std::vector<int>::iterator GetSelectedIter(int line);
+
+    void ResetTopology();
+
+public:
+    /* constructor */
+    DisplayDriver(void *);
+    /* destructor */
+    ~DisplayDriver();
+
+    /* display */
+    int DrawMap(bool);
+
+    /* select */
+    int SelectLinesByBox(double, double, double, double);
+    std::vector<double> SelectLineByPoint(double, double, double,
+					  int);
+
+    std::vector<int> GetSelected(bool);
+    int SetSelected(std::vector<int>);
+    std::vector<int> GetSelectedVertex(double, double, double);
+
+    /* general */
+    void CloseMap();
+    int  OpenMap(const char *, const char *, bool);
+    void ReloadMap();
+    void SetDevice(void *);
+
+    /* set */
+    void SetRegion(double, double, double, double,
+		   double, double,
+		   double, double,
+		   double, double);
+
+    void UpdateSettings(unsigned long,
+			bool, unsigned long, /* enabled, color */
+			bool, unsigned long,
+			bool, unsigned long,
+			bool, unsigned long,
+			bool, unsigned long,
+			bool, unsigned long,
+			bool, unsigned long,
+			bool, unsigned long,
+			bool, unsigned long,
+			bool, unsigned long,
+			bool, unsigned long,
+			int,
+			double);
+};
+
+#endif /* __DRIVER_H__ */

Deleted: grass/trunk/gui/wxpython/vdigit/driver.i
===================================================================
--- grass/trunk/gui/wxpython/display_driver/driver.i	2008-01-07 12:38:19 UTC (rev 29593)
+++ grass/trunk/gui/wxpython/vdigit/driver.i	2008-01-08 11:48:03 UTC (rev 29601)
@@ -1,16 +0,0 @@
-/* File: driver.i */
-
-%module grass6_wxdriver
-%{
-#include <grass/gis.h>
-#include <grass/gisdefs.h>
-#include <grass/Vect.h>
-#include <grass/vect/dig_structs.h>
-#include "driver.h"
-%}
-
-%include "std_vector.i" 
-namespace std { 
-   %template(IntVector) vector<int>;
-   %template(DoubleVector) vector<double>;
-}

Copied: grass/trunk/gui/wxpython/vdigit/driver.i (from rev 29600, grass/trunk/gui/wxpython/display_driver/driver.i)
===================================================================
--- grass/trunk/gui/wxpython/vdigit/driver.i	                        (rev 0)
+++ grass/trunk/gui/wxpython/vdigit/driver.i	2008-01-08 11:48:03 UTC (rev 29601)
@@ -0,0 +1,16 @@
+/* File: driver.i */
+
+%module grass6_wxdriver
+%{
+#include <grass/gis.h>
+#include <grass/gisdefs.h>
+#include <grass/Vect.h>
+#include <grass/vect/dig_structs.h>
+#include "driver.h"
+%}
+
+%include "std_vector.i" 
+namespace std { 
+   %template(IntVector) vector<int>;
+   %template(DoubleVector) vector<double>;
+}

Added: grass/trunk/gui/wxpython/vdigit/line.cpp
===================================================================
--- grass/trunk/gui/wxpython/vdigit/line.cpp	                        (rev 0)
+++ grass/trunk/gui/wxpython/vdigit/line.cpp	2008-01-08 11:48:03 UTC (rev 29601)
@@ -0,0 +1,126 @@
+/**
+   \file line.cpp
+
+   \brief Line manipulation
+
+   This program is free software under the GNU General Public
+   License (>=v2). Read the file COPYING that comes with GRASS
+   for details.
+
+   \author (C) by The GRASS development team
+   Martin Landa <landa.martin gmail.com>
+
+   \date 2008 
+*/
+
+#include "driver.h"
+#include "digit.h"
+
+/**
+   \brief Delete selected lines
+
+   \return number of deleted lines
+   \return -1 on error
+*/
+int Digit::DeleteSelectedLines()
+{
+    int nlines = 0;
+
+    if (!display->mapInfo) {
+	return -1;
+    }
+
+    for(std::vector<int>::iterator i = display->selected.begin(), e = display->selected.end();
+	i != e; ++i) {
+	Vect_delete_line(display->mapInfo, *i);
+    }
+
+    return nlines;
+}
+
+/**
+   \brief Add new line
+
+   For feature type see include/vect/dig_defines.h
+       #define GV_POINT      0x01
+       #define GV_LINE	     0x02
+       #define GV_BOUNDARY   0x04
+       #define GV_CENTROID   0x08
+
+       (unsupported)
+       #define GV_FACE       0x10
+1       #define GV_KERNEL     0x20
+       #define GV_AREA	     0x40
+       #define GV_VOLUME     0x80
+
+   \param type   feature type
+   \param coords pairs of coordinates list
+   \param with_z 3D?
+
+   \return 1 on success
+   \return -1 on failure
+*/
+int Digit::AddLine(int type, std::vector<double> coords, bool with_z, int layer, int cat)
+{
+    int i, npoints;
+
+    struct line_pnts *Points;
+    struct line_cats *Cats;
+
+    if (!display->mapInfo) {
+	return -1;
+    }
+
+    npoints = coords.size() / (with_z ? 3 : 2);
+    if (coords.size() != npoints * (with_z ? 3 : 2)) {
+	return -1;
+    }
+
+    /* TODO: 3D */
+    if (!(type & GV_POINTS) && !(type & GV_LINES)) {
+	return -1;
+    }
+
+    if (layer < -1) {
+	return -1;
+    }
+
+    Points = Vect_new_line_struct();
+    Cats = Vect_new_cats_struct();
+
+    Vect_cat_set(Cats, layer, cat);
+
+    if (cat > GetCategory(layer)) {
+	SetCategory(layer, cat); /* set up max category for layer */
+    }
+
+    i = 0;
+    while (i < coords.size()) {
+	if (with_z) {
+	    Vect_append_point(Points, coords[i], coords[i+1], coords[i+2]);
+	    i += 3;
+	}
+	else {
+	    Vect_append_point(Points, coords[i], coords[i+1], 0.0);
+	    i += 2;
+	}
+    }
+
+    if (type & GV_BOUNDARY) { /* close boundary */
+	int last = Points->n_points-1;
+	if (Vect_points_distance(Points->x[0], Points->x[0], Points->z[0],
+				 Points->x[last], Points->x[last], Points->z[last],
+				 with_z) <= display->settings.threshold) {
+	    Points->x[last] = Points->x[0];
+	    Points->y[last] = Points->y[0];
+	    Points->z[last] = Points->z[0];
+	}
+    }
+
+    Vect_write_line(display->mapInfo, type, Points, Cats);
+
+    Vect_destroy_line_struct(Points);
+    Vect_destroy_cats_struct(Cats);
+
+    return 1;
+}



More information about the grass-commit mailing list