Kaynağa Gözat

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 yıl önce
ebeveyn
işleme
8992a57570

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

@@ -96,28 +96,34 @@ class VectorDBInfo(VectorDBInfoBase):
                                  coord = (float(queryCoords[0]), float(queryCoords[1])),
                                  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
         
         # 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()
-        for key, value in data[0].iteritems():
-            if key == 'Attributes':
-                continue
+        for key in ['Category', 'Layer', 'Table', 'Id']:
             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
     
     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 grass.script import core as grass
+import grass.script as grass
 
 haveCtypes = False
 
@@ -630,55 +630,89 @@ class MapFrame(SingleMapFrame):
             pgnum = self.layerbook.GetPageIndex(self.page)
             if pgnum > -1:
                 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 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
         qdist = 10.0 * ((self.Map.region['e'] - self.Map.region['w']) / self.Map.width)
         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()
         vect = list()
         rcmd = ['r.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
         self.tmpreg = os.getenv("GRASS_REGION")
         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),
                                                           ','.join(vect)))
         # 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):
         """!Restore settings after querying (restore GRASS_REGION)
@@ -744,29 +773,15 @@ class MapFrame(SingleMapFrame):
         if hasattr(self, "tmpreg"):
             del self.tmpreg
         
-    def QueryVector(self, x, y):
+    def QueryVector(self, east, north, qdist, posWindow, layer):
         """!Query vector map layer features
 
         Attribute data of selected vector object are displayed in GUI dialog.
         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']:
             mode = 'display'
         else:
@@ -812,7 +827,7 @@ class MapFrame(SingleMapFrame):
                     qlayer = self.AddTmpVectorMapLayer(mapName, cats, useId = False)
                 
                 # 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)
                 
                 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
 
 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.settings      import UserSettings
 from gui_core.mapwindow import MapWindow
@@ -1169,22 +1169,15 @@ class BufferedWindow(MapWindow, wx.Window):
             
         elif self.mouse["use"] == "query":
             # 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":
             # 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()
         if self.mouse["use"] == "query":
             # 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'):
             self.lmgr.nviz.FindWindowById(
                     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.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"""
         size = self.GetClientSizeTuple()
-        result = self._display.QueryMap(event.GetX(), size[1] - event.GetY())
+        result = self._display.QueryMap(x, size[1] - y)
         if result:
             self.qpoints.append((result['x'], result['y'], result['z']))
             self.log.WriteLog("%-30s: %.3f" % (_("Easting"),   result['x']))