[GRASS-SVN] r44903 - in grass/trunk: gui/wxpython/gui_modules include lib/vector/vedit

svn_grass at osgeo.org svn_grass at osgeo.org
Fri Jan 7 13:01:17 EST 2011


Author: martinl
Date: 2011-01-07 10:01:17 -0800 (Fri, 07 Jan 2011)
New Revision: 44903

Modified:
   grass/trunk/gui/wxpython/gui_modules/mapdisp_window.py
   grass/trunk/gui/wxpython/gui_modules/vdigit.py
   grass/trunk/gui/wxpython/gui_modules/wxvdigit.py
   grass/trunk/gui/wxpython/gui_modules/wxvdriver.py
   grass/trunk/include/vedit.h
   grass/trunk/lib/vector/vedit/render.c
Log:
wxGUI/vdigit pythonized: delete feature works


Modified: grass/trunk/gui/wxpython/gui_modules/mapdisp_window.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/mapdisp_window.py	2011-01-06 22:48:05 UTC (rev 44902)
+++ grass/trunk/gui/wxpython/gui_modules/mapdisp_window.py	2011-01-07 18:01:17 UTC (rev 44903)
@@ -1727,16 +1727,13 @@
                     drawSeg = True
                 else:
                     drawSeg = False
-
-                nselected = digitClass.GetDisplay().SelectLinesByBox(pos1, pos2,
-                                                               digitClass.GetSelectType(),
-                                                               drawSeg)
-                    
+                
+                nselected = digitClass.GetDisplay().SelectLinesByBox(bbox = (pos1, pos2),
+                                                                     drawSeg = drawSeg)
                 if nselected == 0:
-                    if digitClass.GetDisplay().SelectLineByPoint(pos1,
-                                                           digitClass.GetSelectType()) is not None:
+                    if digitClass.GetDisplay().SelectLineByPoint(pos1) is not None:
                         nselected = 1
-        
+                
         if nselected > 0:
             if digitToolbar.GetAction() in ("moveLine",
                                             "moveVertex"):
@@ -2317,9 +2314,9 @@
                     # remove last vertex & line
                     if len(self.vdigitMove['id']) > 1:
                         self.vdigitMove['id'].pop()
-
+                
                 self.UpdateMap(render = False, renderVector = False)
-
+            
             elif digitToolbar.GetAction() in ["deleteLine", "moveLine", "splitLine",
                                               "addVertex", "removeVertex", "moveVertex",
                                               "copyCats", "flipLine", "mergeLine",
@@ -2329,9 +2326,9 @@
                 digitClass.GetDisplay().SetSelected([])
                 if digitToolbar.GetAction() in ["moveLine", "moveVertex", "editLine"] and \
                         hasattr(self, "vdigitMove"):
-
-                    del self.vdigitMove
                     
+                    del self.vdigitMove
+                
                 elif digitToolbar.GetAction() == "copyCats":
                     try:
                         del self.copyCatsList
@@ -2358,9 +2355,12 @@
             self.redrawAll = True
 
     def OnMiddleUp(self, event):
-        """!
-        Middle mouse button released
+        """!Middle mouse button released
         """
+        if self.parent.toolbars['vdigit']:
+            event.Skip()
+            return
+        
         self.mouse['end'] = event.GetPositionTuple()[:]
         
         # set region in zoom or pan
@@ -2376,8 +2376,7 @@
         self.parent.StatusbarUpdate()
         
     def OnMouseEnter(self, event):
-        """!
-        Mouse entered window and no mouse buttons were pressed
+        """!Mouse entered window and no mouse buttons were pressed
         """
         if self.parent.GetLayerManager().gcpmanagement:
             if self.parent.toolbars['gcpdisp']:
@@ -2391,8 +2390,7 @@
             event.Skip()
 
     def OnMouseMoving(self, event):
-        """!
-        Motion event and no mouse buttons were pressed
+        """!Motion event and no mouse buttons were pressed
         """
         digitToolbar = self.parent.toolbars['vdigit']
         if self.mouse["use"] == "pointer" and digitToolbar:

Modified: grass/trunk/gui/wxpython/gui_modules/vdigit.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/vdigit.py	2011-01-06 22:48:05 UTC (rev 44902)
+++ grass/trunk/gui/wxpython/gui_modules/vdigit.py	2011-01-07 18:01:17 UTC (rev 44903)
@@ -39,15 +39,17 @@
 from units import Units
 from preferences import globalSettings as UserSettings
 try:
-    from wxvdigit  import IVDigit
+    from wxvdigit  import IVDigit, GV_LINES
     haveVDigit = True
-    GV_LINES = 10
     errorMsg = ''
 except ImportError, err:
     haveVDigit = False
-    GV_LINES = None
     errorMsg = err
-    
+    GV_LINES = -1
+    class IVDigit:
+        def __init__(self):
+            pass
+
 class VDigit(IVDigit):
     def __init__(self, mapwindow):
         """!Base class of vector digitizer

Modified: grass/trunk/gui/wxpython/gui_modules/wxvdigit.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/wxvdigit.py	2011-01-06 22:48:05 UTC (rev 44902)
+++ grass/trunk/gui/wxpython/gui_modules/wxvdigit.py	2011-01-07 18:01:17 UTC (rev 44903)
@@ -25,6 +25,7 @@
 from grass.lib.grass  import *
 from grass.lib.vector import *
 from grass.lib.vedit  import *
+from grass.lib.dbmi   import *
 
 class IVDigit:
     def __init__(self, mapwindow):
@@ -32,7 +33,7 @@
         
         @parem mapwindow reference for map window (BufferedWindow)
         """
-        self.mapInfo   = None      # pointer to Map_info
+        self.poMapInfo   = None      # pointer to Map_info
         self.mapWindow = mapwindow
         
         if not mapwindow.parent.IsStandalone():
@@ -64,7 +65,7 @@
         self.changesetCurrent = -1 # first changeset to apply
         self.changesetEnd     = -1 # last changeset to be applied
         
-        if self.mapInfo:
+        if self.poMapInfo:
             self.InitCats()
         
     def __del__(self):
@@ -92,8 +93,8 @@
             name = name.value
             mapset = mapset.value
 
-        if (name == Vect_get_name(self.mapInfo) and \
-                mapset == Vect_get_mapset(self.mapInfo)):
+        if (name == Vect_get_name(self.poMapInfo) and \
+                mapset == Vect_get_mapset(self.poMapInfo)):
             return None
 
         bgMapInfo = map_info()
@@ -121,13 +122,13 @@
         @param add True to add, otherwise delete
         @param line feature id
         """
-        if not self.mapInfo:
+        if not self.poMapInfo:
             return 
         
-        if not Vect_line_alive(self.mapInfo, line):
+        if not Vect_line_alive(self.poMapInfo, line):
             return
         
-        offset = Vect_get_line_offset(self.mapInfo, line)
+        offset = Vect_get_line_offset(self.poMapInfo, line)
         
         if not self.changesets.has_key(changeset):
             self.changesets[changeset] = list()
@@ -147,6 +148,15 @@
     def _removeActionFromChangeset(self):
         pass
 
+    def _listToIList(self, plist):
+        """!Generate from list struct_ilist
+        """
+        ilist = Vect_new_list()
+        for val in plist:
+            Vect_list_append(ilist, val)
+        
+        return ilist
+        
     def AddFeature(self, ftype, points):
         """!Add new feature
         
@@ -162,7 +172,8 @@
             layer = UserSettings.Get(group = 'vdigit', key = "layer", subkey = 'value')
             cat   = self.cats.get(layer, 1)
         
-        snap, thresh = self._display.GetThreshold()
+        thresh = self._display.GetThreshold()
+        snap   = self._display.GetSnapMode()
         
         bgmap = str(UserSettings.Get(group = 'vdigit', key = 'bgmap',
                                      subkey = 'value', internal = True))
@@ -193,13 +204,91 @@
     def DeleteSelectedLines(self):
         """!Delete selected features
 
-        @return number of deleted lines
+        @return number of deleted features
         """
-        nlines = self.digit.DeleteLines(UserSettings.Get(group='vdigit', key='delRecord', subkey='enabled'))
+        deleteRec = UserSettings.Get(group = 'vdigit', key = 'delRecord', subkey = 'enabled')
+        if not self.poMapInfo:
+            return -1
         
+        n_dblinks = Vect_get_num_dblinks(self.poMapInfo)
+        Cats_del = None
+        
+        # collect categories for delete if requested
+        if deleteRec:
+            poCats    = Vect_new_cats_struct()
+            poCatsDel = Vect_new_cats_struct()
+            for i in self._display.selected['ids']:
+                if Vect_read_line(self.poMapInfo, None, poCats, i) < 0:
+                    Vect_destroy_cats_struct(poCatsDel)
+                    self._errorReadLine()
+                    return -1
+                
+                cats = poCats.contents
+                for j in range(cats.n_cats):
+                    Vect_cat_set(poCatsDel, cats.field[j], cats.cat[j])
+            
+            Vect_destroy_cats_struct(poCats)
+        
+        # register changeset
+        changeset = self._addActionsBefore()
+        
+        ilist = self._listToIList(self._display.selected['ids'])
+        nlines = Vedit_delete_lines(self.poMapInfo, ilist)
+        Vect_destroy_list(ilist)
+        self._display.selected['ids'] = list()
+        
+        if nlines > 0 and deleteRec:
+            handle  = dbHandle()
+            poHandle = pointer(handle)
+            stmt    = dbString()
+            poStmt   = pointer(stmt)
+            
+            for dblink in range(n_dblinks):
+                poFi = Vect_get_dblink(self.poMapInfo, dblink)
+                if poFi is None:
+                    self._errorDbLink(dblink)
+                    return -1
+                
+                Fi = poFi.contents
+                poDriver = db_start_driver(Fi.driver)
+                if poDriver is None:
+                    self._errorDriver(Fi.driver)
+                    return -1
+                
+                db_init_handle(poHandle)
+                db_set_handle(poHandle, Fi.database, None)
+                if db_open_database(poDriver, poHandle) != DB_OK:
+                    self._errorDbDatabase(Fi.driver, Fi.database)
+                    return -1
+                
+                db_init_string(poStmt)
+                db_set_string(poStmt, "DELETE FROM %s WHERE" % Fi.table)
+                n_cats = 0;
+                catsDel = CatsDel.contents
+                for c in range(catsDel.n_cats):
+                    if catsDel.field[c] == Fi.number:
+                        if n_cats > 0:
+                            db_append_string(poStmt, " or")
+                    
+		    db_append_string(poStmt, " %s = %d" % (Fi.key, catsDel.cat[c]))
+		    n_cats += 1
+                
+                Vect_cat_del(poCatsDel, Fi.number)
+                
+                if n_cats and \
+                        db_execute_immediate(poDriver, poStmt) != DB_OK:
+                    self._errorDbExecute(db_get_string(poStmt))
+                    return -1
+                
+                db_close_database(poDriver)
+                db_shutdown_driver(poDriver)
+        
+        if poCatsDel:
+            Vect_destroy_cats_struct(poCatsDel)
+        
         if nlines > 0:
             self.toolbar.EnableUndo()
-            
+        
         return nlines
 
     def MoveSelectedLines(self, move):
@@ -601,7 +690,7 @@
         
         name, mapset = name.split('@')
         try:
-            self.mapInfo = self._display.OpenMap(str(name), str(mapset), True)
+            self.poMapInfo = self._display.OpenMap(str(name), str(mapset), True)
         except SystemExit:
             pass
         
@@ -628,7 +717,7 @@
     def CloseMap(self):
         """!Close currently open vector map
         """
-        if not self.mapInfo:
+        if not self.poMapInfo:
             return
         
         self._display.CloseMap()
@@ -640,29 +729,29 @@
         @return -1 on error
         """
         self.cats.clear()
-        if not self.mapInfo:
+        if not self.poMapInfo:
             return -1
         
-        ndblinks = Vect_get_num_dblinks(self.mapInfo)
+        ndblinks = Vect_get_num_dblinks(self.poMapInfo)
         for i in range(ndblinks):
-            fi = Vect_get_dblink(self.mapInfo, i).contents
+            fi = Vect_get_dblink(self.poMapInfo, i).contents
             if fi:
                 self.cats[fi.number] = None
         
         # find max category
-        nfields = Vect_cidx_get_num_fields(self.mapInfo)
+        nfields = Vect_cidx_get_num_fields(self.poMapInfo)
         Debug.msg(2, "wxDigit.InitCats(): nfields=%d", nfields)
         
         for i in range(nfields):
-            field = Vect_cidx_get_field_number(self.mapInfo, i)
-            ncats = Vect_cidx_get_num_cats_by_index(self.mapInfo, i)
+            field = Vect_cidx_get_field_number(self.poMapInfo, i)
+            ncats = Vect_cidx_get_num_cats_by_index(self.poMapInfo, i)
             if field <= 0:
                 continue
             for j in range(ncats):
                 cat = c_int()
                 type = c_int()
                 id = c_int()
-                Vect_cidx_get_cat_by_index(self.mapInfo, i, j,
+                Vect_cidx_get_cat_by_index(self.poMapInfo, i, j,
                                            byref(cat), byref(type), byref(id))
                 if self.cats.has_key(field):
                     if cat > self.cats[field]:
@@ -697,10 +786,10 @@
         @return -1 on error
         @return feature id of new feature
         """
-        if not self.mapInfo:
+        if not self.poMapInfo:
             return -1
         
-        is3D = bool(Vect_is_3d(self.mapInfo))
+        is3D = bool(Vect_is_3d(self.poMapInfo))
         
         Debug.msg(2, "IVDigit._addFeature(): npoints=%d, layer=%d, cat=%d, snap=%d",
                   len(coords), layer, cat, snap)
@@ -717,43 +806,43 @@
                             message = _("Unable to open background vector map <%s>") % bgmap)
                 return -1
         
-        Points = Vect_new_line_struct()
-        Cats   = Vect_new_cats_struct() 
+        poPoints = Vect_new_line_struct()
+        poCats   = Vect_new_cats_struct() 
         
         # set category
         if layer > 0 and \
                 (type != GV_BOUNDARY or \
                      (type == GV_BOUNDARY and self.settings['catBoundary'])):
-            Vect_cat_set(Cats, layer, cat)
+            Vect_cat_set(poCats, layer, cat)
             self.cats[layer] = max(cat, self.cats.get(layer, 0))
         
         # append points
         for c in coords:
-            Vect_append_point(Points, c[0], c[1], 0.0)
+            Vect_append_point(poPoints, c[0], c[1], 0.0)
         
         if type & GV_BOUNDARY:
             # close boundary
-            cPoints = Points.contents
-            last = cPoints.n_points - 1
-            if Vect_points_distance(cPoints.x[0], cPoints.x[0], cPoints.z[0],
-                                    cPoints.x[last], cPoints.x[last], cPoints.z[last],
+            points = poPoints.contents
+            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],
                                     is3D) <= threshold:
-                cPoints.x[last] = cPoints.x[0]
-                cPoints.y[last] = cPoints.y[0]
-                cPoints.z[last] = cPoints.z[0]
+                points.x[last] = points.x[0]
+                points.y[last] = points.y[0]
+                points.z[last] = points.z[0]
         
         if snap != NO_SNAP and (type & (GV_POINT | GV_LINES)):
             # apply snapping (node or vertex)
             modeSnap = not (snap == SNAP)
             if bgMapInfo:
-                Vedit_snap_line(self.mapInfo, byref(bgMapInfo), 1,
-                                -1, Points, threshold, modeSnap)
+                Vedit_snap_line(self.poMapInfo, byref(bgMapInfo), 1,
+                                -1, poPoints, threshold, modeSnap)
             else:
-                # Vedit_snap_line(self.mapInfo, None, 0,
-                #                -1, Points, threshold, modeSnap)
+                # Vedit_snap_line(self.poMapInfo, None, 0,
+                #                -1, poPoints, threshold, modeSnap)
                 pass
         
-        newline = Vect_write_line(self.mapInfo, type, Points, Cats)
+        newline = Vect_write_line(self.poMapInfo, type, poPoints, poCats)
         if newline < 0:
             self._errorWriteLine()
             return -1
@@ -765,37 +854,37 @@
             cleft = c_int()
             cright = c_int()
             
-            Vect_get_line_areas(self.mapInfo, newline,
+            Vect_get_line_areas(self.poMapInfo, newline,
                                 byref(cleft), byref(cright))
             left = cleft.value
             right = cright.value
             
             # check if area exists and has no centroid inside
             if layer > 0 and (left > 0 or right > 0):
-                Vect_cat_set(Cats, layer, cat)
+                Vect_cat_set(poCats, layer, cat)
                 self.cats[layer] = max(cat, self.cats.get(layer, 0))
             
             x = c_double()
             y = c_double()
             if left > 0 and \
-                    Vect_get_area_centroid(self.mapInfo, left) == 0:
-                if Vect_get_area_points(self.mapInfo, left, bpoints) > 0 and \
+                    Vect_get_area_centroid(self.poMapInfo, left) == 0:
+                if Vect_get_area_points(self.poMapInfo, left, bpoints) > 0 and \
                         Vect_find_poly_centroid(bpoints, byref(x), byref(y)) == 0:
                     Vect_reset_line(bpoints)
                     Vect_append_point(bpoints, x.value, y.value, 0.0)
-                    if Vect_write_line(self.mapInfo, GV_CENTROID,
-                                       bpoints, Cats) < 0:
+                    if Vect_write_line(self.poMapInfo, GV_CENTROID,
+                                       bpoints, poCats) < 0:
                         self._errorWriteLine()
                         return -1
             
             if right > 0 and \
-                    Vect_get_area_centroid(self.mapInfo, right) == 0:
-                if Vect_get_area_points(byref(self.mapInfo), right, bpoints) > 0 and \
+                    Vect_get_area_centroid(self.poMapInfo, right) == 0:
+                if Vect_get_area_points(byref(self.poMapInfo), right, bpoints) > 0 and \
                         Vect_find_poly_centroid(bpoints, byref(x), byref(y)) == 0:
                     Vect_reset_line(bpoints)
                     Vect_append_point(bpoints, x.value, y.value, 0.0)
-                    if Vect_write_line(byref(self.mapInfo), GV_CENTROID,
-                                       bpoints, Cats) < 0:
+                    if Vect_write_line(byref(self.poMapInfo), GV_CENTROID,
+                                       bpoints, poCats) < 0:
                         self._errorWriteLine()
                         return -1
             Vect_destroy_line_struct(bpoints)
@@ -805,10 +894,10 @@
         
         # break at intersection
         if self.settings['breakLines']:
-            self._breakLineAtIntersection(newline, Points, changeset)
+            self._breakLineAtIntersection(newline, poPoints, changeset)
         
-        Vect_destroy_line_struct(Points)
-        Vect_destroy_cats_struct(Cats)
+        Vect_destroy_line_struct(poPoints)
+        Vect_destroy_cats_struct(poCats)
         
         # close background map if opened
         if bgMapInfo:

Modified: grass/trunk/gui/wxpython/gui_modules/wxvdriver.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/wxvdriver.py	2011-01-06 22:48:05 UTC (rev 44902)
+++ grass/trunk/gui/wxpython/gui_modules/wxvdriver.py	2011-01-07 18:01:17 UTC (rev 44903)
@@ -34,23 +34,25 @@
         
         @param device    wx.PseudoDC device where to draw vector objects
         @param deviceTmp wx.PseudoDC device where to draw temporary vector objects
+        @param mapOng    Map Object (render.Map)
+        @param log       logging device (None to discard messages)
         """
         G_gisinit('')             # initialize GRASS libs
         
-        self.mapInfoObj = None    # open vector map (Map_Info structure)
-        self.mapInfo    = None    # pointer to self.mapInfoObj
+        self.mapInfo   = None     # open vector map (Map_Info structure)
+        self.poMapInfo = None     # pointer to self.mapInfo
+        self.is3D      = False    # is open vector map 3D
         
         self.dc      = device     # PseudoDC devices
         self.dcTmp   = deviceTmp
         self.mapObj  = mapObj
         self.region  = mapObj.GetCurrentRegion()
         self.log     = log        # log device
+
+        # GRASS lib
+        self.poPoints = Vect_new_line_struct()
+        self.poCats   = Vect_new_cats_struct()
         
-        # objects used by GRASS vector library
-        self.points       = line_pnts()
-        self.pointsScreen = list()
-        self.cats         = line_cats()
-        
         # selected objects
         self.selected = {
             'field'   : -1,      # field number
@@ -109,18 +111,21 @@
             'vertex'      : 0,
             }
         
-        self.drawSelected = None
+        self.drawSelected = False
         self.drawSegments = False
-
+        
         self.UpdateSettings()
-
+        
         Vect_set_fatal_error(GV_FATAL_PRINT)
         
-    # def __del__(self):
-    #     """!Close currently open vector map"""
-    #     if self.mapInfo:
-    #         self.CloseMap()
-    
+    def __del__(self):
+        """!Close currently open vector map"""
+        if self.poMapInfo:
+            self.CloseMap()
+        
+        Vect_destroy_line_struct(self.poPoints)
+        Vect_destroy_cats_struct(self.poCats)
+        
     def _cell2Pixel(self, east, north, elev):
         """!Conversion from geographic coordinates (east, north)
         to screen (x, y)
@@ -176,8 +181,11 @@
         pdc.SetId(dcId) # 0 | 1 (selected)
         
         Debug.msg(3, "_drawObject(): type=%d npoints=%d", robj.type, robj.npoints)
-        points = list() 
-        self._setPen(robj.type, pdc)
+        points = list()
+        if self._isSelected(robj.fid):
+            pdc.SetPen(wx.Pen(self.settings['highlight'], self.settings['lineWidth'], wx.SOLID))
+        else:
+            self._setPen(robj.type, pdc)
         
         for i in range(robj.npoints):
             p = robj.point[i]
@@ -296,9 +304,32 @@
     def _printIds(self):
         pass
 
-    def _isSelected(self, featId, foo = False):
+    def _isSelected(self, line, force = False):
+        """!Check if vector object selected?
+   
+        @param line feature id
+
+        @return True if vector object is selected
+        @return False if vector object is not selected
+        """
+        if len(self.selected['cats']) < 1 or force:
+            # select by id
+            if line in self.selected['ids']:
+                return True
+        else: 
+            # select by cat
+            cats = self.poCats.contents
+            for i in range(cats.n_cats):
+                if cats.field[i] == self.selected['field'] and \
+                        cats.cat[i] in self.selected['cats']:
+                    # remember id
+                    # -> after drawing all features selected.cats is reseted */
+                    self.selected['ids'].append(line)
+                    return True
+        
         return False
 
+
     def _isDuplicated(self, featId):
         return False
 
@@ -330,10 +361,10 @@
         """
         Debug.msg(1, "DisplayDriver.DrawMap(): force=%d", force)
         
-        if not self.mapInfo or not self.dc or not self.dcTmp:
+        if not self.poMapInfo or not self.dc or not self.dcTmp:
             return -1
         
-        rlist = Vedit_render_map(self.mapInfo, byref(self._getRegionBox()), self._getDrawFlag(),
+        rlist = Vedit_render_map(self.poMapInfo, byref(self._getRegionBox()), self._getDrawFlag(),
                                  self.region['center_easting'], self.region['center_northing'],
                                  self.mapObj.width, self.mapObj.height,
                                  max(self.region['nsres'], self.region['ewres'])).contents
@@ -354,40 +385,167 @@
         # list of ids - see IsSelected()
         ### selected.field = -1;
         ### Vect_reset_list(selected.cats);
+
+    def _getSelectType(self):
+        """!Get type(s) to be selected
+
+        Used by SelectLinesByBox() and SelectLinesByPoint()
+        """
+        ftype = 0
+        for feature in (('point',    GV_POINT),
+                        ('line',     GV_LINE),
+                        ('centroid', GV_CENTROID),
+                        ('boundary', GV_BOUNDARY)):
+            if UserSettings.Get(group = 'vdigit', key = 'selectType',
+                                subkey = [feature[0], 'enabled']):
+                ftype |= feature[1]
         
-    def SelectLinesByBox(self):
-        pass
+        return ftype
 
-    def SelectLineByPoint(self):
-        pass
+    def SelectLinesByBox(self, bbox, drawSeg):
+        """!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 bbox bounding box definition
+        @param drawSeg True to draw segments of line
+
+        @return number of selected features
+        @return -1 on error
+        """
+        if not self.poMapInfo:
+            return -1
+        
+        self.drawSegments = drawSeg
+        self.drawSelected = True
+    
+        # select by ids
+        self.selected['cats'] = list()
+
+        poList = Vect_new_list()
+        poBbox = Vect_new_line_struct()
+        for p in bbox:
+            Vect_append_point(poBbox, p[0], p[1], 0.0)
+        
+        Vect_select_lines_by_polygon(self.poMapInfo, poBbox,
+                                     0, None, # isles
+                                     self._getSelectType(), poList)
+        
+        flist = poList.contents
+        nlines = flist.n_values
+        for i in range(nlines):
+            line = flist.value[i]
+            if UserSettings.Get(group = 'vdigit', key = 'selectInside',
+                                subkey = 'enabled'):
+                inside = True
+                Vect_read_line(self.poMapInfo, self.poPoints, None, line)
+                points = poPoints.contents
+                for p in range(points.n_points):
+                    if not Vect_point_in_poly(points.x[p], points.y[p],
+                                              byref(bbox)):
+                        inside = False
+                        break
+                    
+                if not inside:
+                    continue # skip lines just overlapping bbox
+        
+            if not self._isSelected(line):
+                self.selected['ids'].append(line)
+            else:
+                self.selected['ids'].remove(line)
+        
+        Vect_destroy_line_struct(poBbox)
+        Vect_destroy_list(poList)
+        
+        return nlines
+
+    def SelectLineByPoint(self, point):
+        """!Select vector feature by given point in given
+        threshold
+   
+        Only one vector object can be selected. Bounding boxes of
+        all segments are stores.
+        
+        @param point points coordinates (x, y)
+        
+        @return point on line if line found
+        """
+        self.drawSelected = True
+        
+        poFound = Vect_new_list()
+        # select by ids 
+        self.selected['cats'] = list()
+        
+        line_nearest = Vect_find_line_list(self.poMapInfo, point[0], point[1], 0,
+                                           self._getSelectType(), self.GetThreshold(), self.is3D,
+                                           None, poFound)
+        
+        if line_nearest > 0:
+            if not self._isSelected(line_nearest):
+                self.selected['ids'].append(line_nearest)
+            else:
+                self.selected['ids'].remove(line_nearest)
+        
+        px = c_double()
+        py = c_double()
+        pz = c_double()
+	ftype = Vect_read_line(self.poMapInfo, self.poPoints, self.poCats, line_nearest)
+	Vect_line_distance (self.poPoints, point[0], point[1], 0.0, self.is3D,
+			    byref(px), byref(py), byref(pz),
+			    None, None, None)
+        
+	# check for duplicates 
+	if self.settings['highlightDupl']['enabled']:
+            found = poFound.contents
+	    for i in range(found.n_values):
+		line = found.value[i]
+		if line != line_nearest:
+                    self.selected['ids'].append(line)
+	    
+            self.getDuplicates()
+	    
+	    for i in range(found.n_values):
+		line = found.value[i]
+		if line != line_nearest and not self._isDuplicated(line):
+                    self.selected['ids'].remove(line)
+        
+        Vect_destroy_list(poFound)
+        
+        # drawing segments can be very expensive
+        # only one features selected
+        self.drawSegments = True
+        
+        return (px.value, py.value, pz.value)
+    
     def GetSelected(self, grassId = False):
         """!Get ids of selected objects
         
         @param grassId if true return GRASS line ids, false to return PseudoDC ids
-   
+        
         @return list of ids of selected vector objects
         """
         if grassId:
             # return ListToVector(selected.ids);
             pass
-
+        
         dc_ids = list()
-
+        
         if not self.drawSegments:
             dc_ids.append(1)
         else:
             # only first selected feature
-            # Vect_read_line(self.mapInfo, byref(self.points), None,
+            # Vect_read_line(self.poMapInfo, byref(self.points), None,
             # self.selected.ids->value[0]);
-            npoints = self.points.n_points
+            # npoints = self.points.n_points
             # node - segment - vertex - segment - node
-            for i in range(1, 2 * self.points.npoints):
-                dc_ids.append(i)
+            # for i in range(1, 2 * self.points.npoints):
+            #     dc_ids.append(i)
+            pass
         
         return dc_ids
-
-
+    
     def GetSelectedCoord(self):
         pass
 
@@ -399,28 +557,22 @@
 
     def SetSelected(self, ids, layer = -1):
         """!Set selected vector objects
-   
-        @param ids list of feature ids to be set
-        @param layer field number (-1 for ids instead of cats)
+
+        @param list of ids (None to unselect features)
+        @param layer layer number for features selected based on category number
         """
         if ids:
             self.drawSelected = True
         else:
             self.drawSelected = False
-            return
-
+        
         if layer > 0:
             selected.field = layer
-            # VectorToList(selected.cats, id);
+            self.selected['cats'] = ids
         else:
             field = -1
-            # VectorToList(selected.ids, id);
-        
-        return 1
-
-    def UnSelect(self):
-        pass
-
+            self.selected['ids'] = ids
+    
     def GetSelectedVertex(self):
         pass
 
@@ -434,16 +586,15 @@
         @return non-zero on error
         """
         ret = 0
-        if self.mapInfo:
-            if self.mapInfoObj.mode == GV_MODE_RW:
-                # rebuild topology
-                Vect_build_partial(self.mapInfo, GV_BUILD_NONE)
-                Vect_build(self.mapInfo)
+        if self.poMapInfo:
+            # rebuild topology
+            Vect_build_partial(self.poMapInfo, GV_BUILD_NONE)
+            Vect_build(self.poMapInfo)
 
             # close map and store topo/cidx
-            ret = Vect_close(self.mapInfo)
-            del self.mapInfoObj
-            self.mapInfo = self.mapInfoObj = None
+            ret = Vect_close(self.poMapInfo)
+            del self.mapInfo
+            self.poMapInfo = self.mapInfo = None
         
         return ret
     
@@ -458,9 +609,9 @@
         """
         Debug.msg("DisplayDriver.OpenMap(): name=%s mapset=%s updated=%d",
                   name, mapset, update)
-        if not self.mapInfoObj:
-            self.mapInfoObj = Map_info()
-            self.mapInfo = pointer(self.mapInfoObj)
+        if not self.mapInfo:
+            self.mapInfo = Map_info()
+            self.poMapInfo = pointer(self.mapInfo)
         
         # define open level (level 2: topology)
         Vect_set_open_level(2)
@@ -470,15 +621,16 @@
         
         # open existing map
         if update:
-            ret = Vect_open_update(self.mapInfo, name, mapset)
+            ret = Vect_open_update(self.poMapInfo, name, mapset)
         else:
-            ret = Vect_open_old(self.mapInfo, name, mapset)
-
+            ret = Vect_open_old(self.poMapInfo, name, mapset)
+        self.is3D = Vect_is_3d(self.poMapInfo)
+        
         if ret == -1: # error
-            del self.mapInfoObj
-            self.mapInfo = self.mapInfoObj = None
+            del self.mapInfo
+            self.poMapInfo = self.mapInfo = None
         
-        return self.mapInfo
+        return self.poMapInfo
     
     def ReloadMap(self):
         pass
@@ -491,11 +643,11 @@
 
         @return (w,s,b,e,n,t)
         """
-        if not self.mapInfo:
+        if not self.poMapInfo:
             return None
         
         bbox = bound_box()
-        Vect_get_map_box(self.mapInfo, byref(bbox))
+        Vect_get_map_box(self.poMapInfo, byref(bbox))
 
         return bbox.W, bbox.S, bbox.B, \
             bbox.E, bbox.N, bbox.T
@@ -541,10 +693,28 @@
             self.settings[key]['color'] = color
         
     def UpdateRegion(self):
-        """!Update geographical region used by display driver.
+        """!Update geographical region used by display driver
         """
         self.region = self.mapObj.GetCurrentRegion()
         
+    def GetSnapMode(self):
+        """!Get snapping mode
+
+        - snap to vertex
+        - snap to nodes
+        - no snapping
+        
+        @return snap mode
+        """
+        threshold = self.GetThreshold()
+        if threshold > 0.0:
+            if UserSettings.Get(group = 'vdigit', key = 'snapToVertex', subkey = 'enabled'):
+                return SNAPVERTEX
+            else:
+                return SNAP
+        else:
+            return NO_SNAP
+        
     def GetThreshold(self, type = 'snapping', value = None, units = None):
         """!Return threshold value in map units
         
@@ -552,7 +722,7 @@
         @param value threshold to be set up
         @param units units (map, screen)
 
-        @return (snap mode id, threshold value)
+        @return threshold value
         """
         if value is None:
             value = UserSettings.Get(group = 'vdigit', key = type, subkey =' value')
@@ -566,16 +736,7 @@
         if units == "screen pixels":
             # pixel -> cell
             res = max(self.region['nsres'], self.region['ewres'])
-            threshold = value * res
-        else:
-            threshold = value
+            return value * res
         
-        if threshold > 0.0:
-            if UserSettings.Get(group = 'vdigit', key = 'snapToVertex', subkey = 'enabled'):
-                snap = SNAPVERTEX
-            else:
-                snap = SNAP
-        else:
-            snap = NO_SNAP
-
-        return (snap, threshold)
+        return value
+        

Modified: grass/trunk/include/vedit.h
===================================================================
--- grass/trunk/include/vedit.h	2011-01-06 22:48:05 UTC (rev 44902)
+++ grass/trunk/include/vedit.h	2011-01-07 18:01:17 UTC (rev 44903)
@@ -49,9 +49,10 @@
 
 struct robject {
     /* object to be rendered */
+    int            fid;       /* feature id */
     int            type;
     int            npoints;
-    struct rpoint *point;   /* list of points */
+    struct rpoint *point;     /* list of points */
 };
 
 struct robject_list {

Modified: grass/trunk/lib/vector/vedit/render.c
===================================================================
--- grass/trunk/lib/vector/vedit/render.c	2011-01-06 22:48:05 UTC (rev 44902)
+++ grass/trunk/lib/vector/vedit/render.c	2011-01-07 18:01:17 UTC (rev 44903)
@@ -156,6 +156,7 @@
     state.type = Vect_read_line(Map, state.Points, NULL, line);
 
     obj = (struct robject *)G_malloc(sizeof(struct robject));
+    obj->fid = line;
     draw = FALSE;
     if (state.type & GV_LINES) {
 	if (state.type == GV_LINE) {



More information about the grass-commit mailing list