wiki:wxGUIDevelopment/Refactoring/wxGUIAPIproposal

Version 7 (modified by rashadkm, 12 years ago) ( diff )

adding new classes

wxGUI API proposal

The proposal does not have to be complete and there can be several different proposals. (All can be listed in different sections on this page for now; if too long a subpage should be created and linked here.)

The API should be used for communication between objects in the wxGUI, for creating new GUI applications (and GUI addons/plugins) and for controlling the wxGUI from the embedded Python command line.

Short proposal based on the current state of refactoring

Note that the main purpose of this API called GrassInterface is to create layer between existing wxGUI classes. This layer enables us to combine existing parts freely.

The term GrassInterface denotes the class which is the root of the object tree. However, all classes which belongs to this tree can sometimes by reffered as GrassInterface too. GrassInterface interface is the abstract base class or interface and its implementation may be also called interfaces because the word interface is overloaded in this case.

Currently the GrassInterface implementations are some proxy objects which provides the right API to the existing classes. However, it is expected that some classes will implement GrassInterface directly.

class Layer(object):

class LayerList(object):
    def GetSelectedLayers(self, checkedOnly=True):

# GrassInterface is a root in the tree of objects/interfaces which compose API
# provides the functionality which should be available to every GUI component
# and is expected to be passed to almost all objects
class GrassInterface:
    def RunCmd(self, *args, **kwargs):

    def Help(self, entry):

    def WriteLog(self, text, wrap=None, priority=1):
        """The meaning and usage of priority is not clear"""

    def WriteCmdLog(self, line, pid=None, switchPage=True):

    def WriteWarning(self, line):

    def WriteError(self, line):

    def GetLayerList(self):

    def GetMapDisplay(self):

    def GetAllMapDisplays(self):

    def GetMapWindow(self):

# more classes should be defined...

Proposing More classes

class WxGUI:
  RASTER = 'raster'
  VECTOR = 'vector'

class Layer(object):

  self.ltype = None
  self.lname  = None
  self.style = None

  def __init__():
    ""TBD""

  def setName(self,n):
   self.lname = n

  def setType(self,t):
    self.ltype = t

  def getName(self):
    return lname
 
  def getType(self):
    return ltype

  def setStyle(style):
    """ 
    (A virtual function)
    style object must be a new class which holds the style info such as color map for vector/raster"
    """
  def getStyle():
   return lstyle

class RasterStyle; #Functionality: TBD
class VectorStyle; #Functionality: TBD

class RasterLayer(Layer):

   def getType(self):
      return wxGUI.RASTER

   def getStyle(self):
    return stlye #instance of RasterStyle

class VectorLayer(Layer):

   def getType(self):
      return wxGUI.VECTOR   

   def getStyle(self):
    return stlye #instance of VectorStyle


class LayerManager(object):

   def addLayer(sef,layer, type):
      """
      Is specifying type is mandatory? We already have access to type = layer.ltype
      I mentioned here to demonstrate the idea to enum instead of hardcorded string for layer type
      """

   def addRaster(self,layer):
       """
       suggest a namespace name instead of wxGUI
       """
       addLayer(layer, wxGUI.RASTER) #no more hardcorded string ex: addLayer(layer,'raster')

   def addVector(self,layer):
       addLayer(layer, wxGUI.VECTOR)

   def addOther(self,layer):
      """TBD"""


class LayerManagerFrame(wx.Frame, layerManager):
  
   def __init__(parent, id, title,size,pos):
      wx.Frame.__init__(parent,id,title,size,pos)
      self.lmgrObject = LayerManager(self) #creates non-gui layer manager

  def getLayerManager(self):
      return self.lmgrObject
  

  def addRasterLayer(self,layer):
   self.lmgrObject.addRasterLayer(layer)
   """ltreeitem can be created using a GUI class"""
   ltreeitem.text = layer.getName()
   ltreeitem.checked = True
   self.ltree.Append(ltreeitem)


class GMFrame(wx.Frame):
    def __init__(self,id,title,size,pos):
        wx.Frame.__init__(id,title,size,pos)

    def SetLayerManager(self,lmgr):
       if type(lmgr) == wx.Frame:
          self.lmgrFrame = lmgr
          self.lmgrAsFrame = True

       if type(lmgr) == wx.Panel:
          self.lmgrFrame = lmgr
          self.lmgrAsFrame = False

    def LmgrAsFrame(self):
       return self.lmgrAsFrame

Simple usage of the above Pseudo code

frame = new GFrame() #gui object
lmgr = LayerManagerFrame() #gui object panel/Frame
frame.SetLayerManager(lmgr)
rlayer = new RasterLayer() #non-gui object
lmgr.addRasterLayer(rlayer)
vlayer = new VectorLayer() #non-gui object
vlayer.setEditable(True)
lmgr.addVectorLayer(vlayer)

PyDispatcher added by vaclav should be used for Event mechanism in the New GUI

New Rendering Model

With the help of GRASS Python modules, It easy to pull chunks from raster data as Numpy array. A new rendering model (in-memory) can be added to wxGUI
which can directly display a numpy array as wx.Image. This will obivously increase the performance of rendering layers because the overhead of
reading and writing data to file (PNG adds a compression during packing and unpacking) can be saved. Also the extent based rendering
will allow to read portion of raster image than whole dataset. Also a tile based technique can be added to this which improves the rendering
performance further.
Basically this will do what d.rast or generally speaking d.* modules do. I agree adding other modules such as d.legend etc is a massive work. But compared
to dealing with large dataset I think its worth it.
.

This is just a breif of what I have. I can provide further details if anyone is interested

TBD: To Be Decided

Note: See TracWiki for help on using the wiki.