Переглянути джерело

wxGUI: reorganize querying, if vector has no db connection, show query output in gui commmand output instead of Nothing found message https://trac.osgeo.org/grass/ticket/1606, https://trac.osgeo.org/grass/ticket/1469, show more layers in attribute dialog - https://trac.osgeo.org/grass/ticket/1522

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@52832 15284696-431f-4ddb-bdfa-cd5b030d7da7
Anna Petrášová 12 роки тому
батько
коміт
8992a57570

+ 23 - 17
gui/wxpython/dbmgr/vinfo.py

@@ -96,28 +96,34 @@ class VectorDBInfo(VectorDBInfoBase):
                                  coord = (float(queryCoords[0]), float(queryCoords[1])),
                                  coord = (float(queryCoords[0]), float(queryCoords[1])),
                                  distance = float(qdist))
                                  distance = float(qdist))
 
 
-        if len(data) < 1 or 'Table' not in data[0]:
+        if len(data) < 1 or all(('Table' not in record) for record in data):
             return None
             return None
         
         
         # process attributes
         # process attributes
-        table = data[0]['Table']
-        for key, value in data[0]['Attributes'].iteritems():
-            if len(value) < 1:
-                value = None
-            else:
-                if self.tables[table][key]['ctype'] != types.StringType:
-                    value = self.tables[table][key]['ctype'] (value)
-                else:
-                    value = unicodeValue(value)
-            self.tables[table][key]['values'].append(value)
-        
         ret = dict()
         ret = dict()
-        for key, value in data[0].iteritems():
-            if key == 'Attributes':
-                continue
+        for key in ['Category', 'Layer', 'Table', 'Id']:
             ret[key] = list()
             ret[key] = list()
-            ret[key].append(value)
-        
+
+        for record in data:
+            if not 'Table' in record:
+                continue
+
+            table = record['Table']
+            for key, value in record['Attributes'].iteritems():
+                if len(value) < 1:
+                    value = None
+                else:
+                    if self.tables[table][key]['ctype'] != types.StringType:
+                        value = self.tables[table][key]['ctype'] (value)
+                    else:
+                        value = unicodeValue(value)
+                self.tables[table][key]['values'].append(value)
+            
+            for key, value in record.iteritems():
+                if key == 'Attributes':
+                    continue
+                if key in ret:
+                    ret[key].append(value)
         return ret
         return ret
     
     
     def SelectFromTable(self, layer, cols = '*', where = None):
     def SelectFromTable(self, layer, cols = '*', where = None):

+ 85 - 70
gui/wxpython/mapdisp/frame.py

@@ -54,7 +54,7 @@ from wxplot.scatter     import ScatterFrame
 
 
 from mapdisp import statusbar as sb
 from mapdisp import statusbar as sb
 
 
-from grass.script import core as grass
+import grass.script as grass
 
 
 haveCtypes = False
 haveCtypes = False
 
 
@@ -630,55 +630,89 @@ class MapFrame(SingleMapFrame):
             pgnum = self.layerbook.GetPageIndex(self.page)
             pgnum = self.layerbook.GetPageIndex(self.page)
             if pgnum > -1:
             if pgnum > -1:
                 self.layerbook.DeletePage(pgnum)
                 self.layerbook.DeletePage(pgnum)
-    
-    
-    def QueryMap(self, x, y):
-        """!Query raster or vector map layers by r/v.what
-        
+
+    def Query(self, x, y, layers):
+        """!Query selected layers. 
+
+        Calls QueryMap in case of raster or more vectors,
+        or QueryVector in case of one vector with db connection.
+
         @param x,y coordinates
         @param x,y coordinates
+        @param layers selected tree item layers
         """
         """
+        num = 0
+        filteredLayers = []
+        for layer in layers:
+            ltype = self.tree.GetPyData(layer)[0]['maplayer'].GetType()
+            if ltype in ('raster', 'rgb', 'his',
+                         'vector', 'thememap', 'themechart'):
+                filteredLayers.append(layer)
+
+        if not filteredLayers:
+            GMessage(parent = self,
+                     message = _('No raster or vector map layer selected for querying.'))
+            return
+            
+        layers = filteredLayers
         # set query snap distance for v.what at map unit equivalent of 10 pixels
         # set query snap distance for v.what at map unit equivalent of 10 pixels
         qdist = 10.0 * ((self.Map.region['e'] - self.Map.region['w']) / self.Map.width)
         qdist = 10.0 * ((self.Map.region['e'] - self.Map.region['w']) / self.Map.width)
         east, north = self.MapWindow.Pixel2Cell((x, y))
         east, north = self.MapWindow.Pixel2Cell((x, y))
+
+        posWindow = self.ClientToScreen((x + self.MapWindow.dialogOffset,
+                                         y + self.MapWindow.dialogOffset))
+
+        isRaster = False
+        nVectors = 0
+        isDbConnection = False
+        for l in layers:
+            maplayer = self.tree.GetPyData(l)[0]['maplayer']
+            if maplayer.GetType() == 'raster':
+                isRaster = True
+                break
+            if maplayer.GetType() == 'vector':
+                nVectors += 1
+                isDbConnection = grass.vector_db(maplayer.GetName())
+
+        if not self.IsPaneShown('3d'):
+            if isRaster or nVectors > 1 or not isDbConnection:
+                self.QueryMap(east, north, qdist, layers)
+            else:
+                self.QueryVector(east, north, qdist, posWindow, layers[0])
+        else:
+            if isRaster:
+                self.MapWindow.QuerySurface(x, y)
+            if nVectors > 1 or not isDbConnection:
+                self.QueryMap(east, north, qdist, layers)
+            elif nVectors == 1:
+                self.QueryVector(east, north, qdist, posWindow, layers[0])
+
+    def QueryMap(self, east, north, qdist, layers):
+        """!Query raster or vector map layers by r/v.what
         
         
-        if not self.IsStandalone():
-            num = 0
-            for layer in self.tree.GetSelections():
-                ltype = self.tree.GetPyData(layer)[0]['maplayer'].GetType()
-                if ltype in ('raster', 'rgb', 'his',
-                             'vector', 'thememap', 'themechart'):
-                    num += 1
-            
-            if num < 1:
-                GMessage(parent = self,
-                         message = _('No raster or vector map layer selected for querying.'))
-                return
-        
+        @param east,north coordinates
+        @param qdist query distance
+        @param layers selected tree items
+        """
         rast = list()
         rast = list()
         vect = list()
         vect = list()
         rcmd = ['r.what', '--v']
         rcmd = ['r.what', '--v']
         vcmd = ['v.what', '--v']
         vcmd = ['v.what', '--v']
         
         
-        if self.IsStandalone():
-            pass
-        else:
-            for layer in self.tree.GetSelections():
-                ltype = self.tree.GetPyData(layer)[0]['maplayer'].GetType()
-                dcmd = self.tree.GetPyData(layer)[0]['cmd']
-                name, found = GetLayerNameFromCmd(dcmd)
-                
-                if not found:
-                    continue
-                if ltype == 'raster':
-                    rast.append(name)
-                elif ltype in ('rgb', 'his'):
-                    for iname in name.split('\n'):
-                        rast.append(iname)
-                elif ltype in ('vector', 'thememap', 'themechart'):
-                    vect.append(name)
-        # rasters are not queried this way in 3D, we don't want them now
-        if self.IsPaneShown('3d'):
-            rast = list()
+        for layer in layers:
+            ltype = self.tree.GetPyData(layer)[0]['maplayer'].GetType()
+            dcmd = self.tree.GetPyData(layer)[0]['cmd']
+            name, found = GetLayerNameFromCmd(dcmd)
+            
+            if not found:
+                continue
+            if ltype == 'raster':
+                rast.append(name)
+            elif ltype in ('rgb', 'his'):
+                for iname in name.split('\n'):
+                    rast.append(iname)
+            elif ltype in ('vector', 'thememap', 'themechart'):
+                vect.append(name)
+
         # use display region settings instead of computation region settings
         # use display region settings instead of computation region settings
         self.tmpreg = os.getenv("GRASS_REGION")
         self.tmpreg = os.getenv("GRASS_REGION")
         os.environ["GRASS_REGION"] = self.Map.SetRegion(windres = False)
         os.environ["GRASS_REGION"] = self.Map.SetRegion(windres = False)
@@ -714,19 +748,14 @@ class MapFrame(SingleMapFrame):
         Debug.msg(1, "QueryMap(): raster=%s vector=%s" % (','.join(rast),
         Debug.msg(1, "QueryMap(): raster=%s vector=%s" % (','.join(rast),
                                                           ','.join(vect)))
                                                           ','.join(vect)))
         # parse query command(s)
         # parse query command(s)
-        if not self.IsStandalone():
-            if rast:
-                self._layerManager.goutput.RunCmd(rcmd,
-                                                  compReg = False,
-                                                  onDone  =  self._QueryMapDone)
-            if vect:
-                self._layerManager.goutput.RunCmd(vcmd,
-                                                  onDone = self._QueryMapDone)
-        else:
-            if rast:
-                RunCommand(rcmd)
-            if vect:
-                RunCommand(vcmd)
+
+        if rast and not self.IsPaneShown('3d'):
+            self._layerManager.goutput.RunCmd(rcmd,
+                                              compReg = False,
+                                              onDone  =  self._QueryMapDone)
+        if vect:
+            self._layerManager.goutput.RunCmd(vcmd,
+                                              onDone = self._QueryMapDone)
         
         
     def _QueryMapDone(self, cmd, returncode):
     def _QueryMapDone(self, cmd, returncode):
         """!Restore settings after querying (restore GRASS_REGION)
         """!Restore settings after querying (restore GRASS_REGION)
@@ -744,29 +773,15 @@ class MapFrame(SingleMapFrame):
         if hasattr(self, "tmpreg"):
         if hasattr(self, "tmpreg"):
             del self.tmpreg
             del self.tmpreg
         
         
-    def QueryVector(self, x, y):
+    def QueryVector(self, east, north, qdist, posWindow, layer):
         """!Query vector map layer features
         """!Query vector map layer features
 
 
         Attribute data of selected vector object are displayed in GUI dialog.
         Attribute data of selected vector object are displayed in GUI dialog.
         Data can be modified (On Submit)
         Data can be modified (On Submit)
         """
         """
-        if not self.tree.layer_selected or \
-                self.tree.GetPyData(self.tree.layer_selected)[0]['type'] != 'vector':
-            GMessage(parent = self,
-                     message = _("No map layer selected for querying."))
-            return
-        
-        posWindow = self.ClientToScreen((x + self.MapWindow.dialogOffset,
-                                         y + self.MapWindow.dialogOffset))
-        
-        qdist = 10.0 * ((self.Map.region['e'] - self.Map.region['w']) /
-                        self.Map.width)
-        
-        east, north = self.MapWindow.Pixel2Cell((x, y))
-        
-        mapName = self.tree.GetPyData(self.tree.layer_selected)[0]['maplayer'].name
+        mapName = self.tree.GetPyData(layer)[0]['maplayer'].name
         
         
-        if self.tree.GetPyData(self.tree.layer_selected)[0]['maplayer'].GetMapset() != \
+        if self.tree.GetPyData(layer)[0]['maplayer'].GetMapset() != \
                 grass.gisenv()['MAPSET']:
                 grass.gisenv()['MAPSET']:
             mode = 'display'
             mode = 'display'
         else:
         else:
@@ -812,7 +827,7 @@ class MapFrame(SingleMapFrame):
                     qlayer = self.AddTmpVectorMapLayer(mapName, cats, useId = False)
                     qlayer = self.AddTmpVectorMapLayer(mapName, cats, useId = False)
                 
                 
                 # set opacity based on queried layer
                 # set opacity based on queried layer
-                opacity = self.tree.GetPyData(self.tree.layer_selected)[0]['maplayer'].GetOpacity(float = True)
+                opacity = self.tree.GetPyData(layer)[0]['maplayer'].GetOpacity(float = True)
                 qlayer.SetOpacity(opacity)
                 qlayer.SetOpacity(opacity)
                 
                 
                 self.MapWindow.UpdateMap(render = False, renderVector = False)
                 self.MapWindow.UpdateMap(render = False, renderVector = False)

+ 10 - 17
gui/wxpython/mapdisp/mapwindow.py

@@ -31,7 +31,7 @@ import wx
 import grass.script as grass
 import grass.script as grass
 
 
 from gui_core.dialogs   import SavedRegion
 from gui_core.dialogs   import SavedRegion
-from core.gcmd          import RunCommand, GException, GError
+from core.gcmd          import RunCommand, GException, GError, GMessage
 from core.debug         import Debug
 from core.debug         import Debug
 from core.settings      import UserSettings
 from core.settings      import UserSettings
 from gui_core.mapwindow import MapWindow
 from gui_core.mapwindow import MapWindow
@@ -1169,22 +1169,15 @@ class BufferedWindow(MapWindow, wx.Window):
             
             
         elif self.mouse["use"] == "query":
         elif self.mouse["use"] == "query":
             # querying
             # querying
-            layers = self.GetSelectedLayer(multi = True)
-            isRaster = False
-            nVectors = 0
-            for l in layers:
-                if l.GetType() == 'raster':
-                    isRaster = True
-                    break
-                if l.GetType() == 'vector':
-                    nVectors += 1
-            
-            if isRaster or nVectors > 1:
-                self.frame.QueryMap(self.mouse['begin'][0],self.mouse['begin'][1])
-            else:
-                self.frame.QueryVector(self.mouse['begin'][0], self.mouse['begin'][1])
-                # clear temp canvas
-                self.UpdateMap(render = False, renderVector = False)
+            if self.frame.IsStandalone():
+                GMessage(parent = self.frame,
+                         message = _("Querying is not implemented in standalone mode of Map Display"))
+                return
+
+            layers = self.GetSelectedLayer(type = 'item', multi = True)
+
+            self.frame.Query(self.mouse['begin'][0],self.mouse['begin'][1], layers)
+            self.UpdateMap(render = False, renderVector = False)
             
             
         elif self.mouse["use"] == "queryVector":
         elif self.mouse["use"] == "queryVector":
             # editable mode for vector map layers
             # editable mode for vector map layers

+ 11 - 22
gui/wxpython/nviz/mapwindow.py

@@ -761,21 +761,15 @@ class GLWindow(MapWindow, glcanvas.GLCanvas):
         self.mouse['end'] = event.GetPositionTuple()
         self.mouse['end'] = event.GetPositionTuple()
         if self.mouse["use"] == "query":
         if self.mouse["use"] == "query":
             # querying
             # querying
-            layers = self.GetSelectedLayer(multi = True)
-            isRaster = False
-            nVectors = 0
-            for l in layers:
-                if l.GetType() == 'raster':
-                    isRaster = True
-                    break
-                if l.GetType() == 'vector':
-                    nVectors += 1
-            
-            if isRaster or nVectors > 1:
-                self.OnQueryMap(event)
-            else:
-                self.OnQueryVector(event)
-                    
+            if self.frame.IsStandalone():
+                GMessage(parent = self.frame,
+                         message = _("Querying is not implemented in standalone mode of Map Display"))
+                return
+
+            layers = self.GetSelectedLayer(type = 'item', multi = True)
+
+            self.frame.Query(self.mouse['begin'][0],self.mouse['begin'][1], layers)
+
         elif self.mouse["use"] in ('arrow', 'scalebar'):
         elif self.mouse["use"] in ('arrow', 'scalebar'):
             self.lmgr.nviz.FindWindowById(
             self.lmgr.nviz.FindWindowById(
                     self.lmgr.nviz.win['decoration'][self.mouse["use"]]['place']).SetValue(False)
                     self.lmgr.nviz.win['decoration'][self.mouse["use"]]['place']).SetValue(False)
@@ -1003,16 +997,11 @@ class GLWindow(MapWindow, glcanvas.GLCanvas):
         
         
         self.render['quick'] = False
         self.render['quick'] = False
         self.Refresh(False)
         self.Refresh(False)
-    
-    def OnQueryMap(self, event):
-        """!Query raster and vector maps"""
-        self.OnQuerySurface(event)
-        self.parent.QueryMap(event.GetX(), event.GetY())
         
         
-    def OnQuerySurface(self, event):
+    def QuerySurface(self, x, y):
         """!Query surface on given position"""
         """!Query surface on given position"""
         size = self.GetClientSizeTuple()
         size = self.GetClientSizeTuple()
-        result = self._display.QueryMap(event.GetX(), size[1] - event.GetY())
+        result = self._display.QueryMap(x, size[1] - y)
         if result:
         if result:
             self.qpoints.append((result['x'], result['y'], result['z']))
             self.qpoints.append((result['x'], result['y'], result['z']))
             self.log.WriteLog("%-30s: %.3f" % (_("Easting"),   result['x']))
             self.log.WriteLog("%-30s: %.3f" % (_("Easting"),   result['x']))