/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/UI/baserenderer.py
ViewVC logotype

Diff of /branches/WIP-pyshapelib-bramz/Thuban/UI/baserenderer.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1866 by bh, Mon Oct 27 13:01:58 2003 UTC revision 1926 by bh, Mon Nov 10 16:57:19 2003 UTC
# Line 20  __version__ = "$Revision$" Line 20  __version__ = "$Revision$"
20  # $Source$  # $Source$
21  # $Id$  # $Id$
22    
23    import sys
24  import traceback  import traceback
25    
26  from Thuban.Model.layer import Layer, RasterLayer  from Thuban.Model.layer import Layer, RasterLayer
# Line 33  if Thuban.Model.resource.has_gdal_suppor Line 34  if Thuban.Model.resource.has_gdal_suppor
34      from gdalwarp import ProjectRasterFile      from gdalwarp import ProjectRasterFile
35    
36    
37    #
38    #       Renderer Extensions
39    #
40    # The renderer extensions provide a way to render layer types defined in
41    # Thuban extensions. The renderer extensions are stored as a list with
42    # (layer_class, draw_function) pairs. If the renderer has to draw a
43    # non-builtin layer type, i.e. a layer that is not a subclass of Layer
44    # or RasterLayer, it iterates through that list, tests whether the layer
45    # to be drawin is an instance of layer_class and if so calls
46    # draw_function with the renderer and the layer as arguments. Since
47    # drawing is done incrementally, the draw_function should return an
48    # iterable. The easiest way is to simply implement the draw_function as
49    # a generator and to yield in suitable places, or to return the empty
50    # tuple.
51    #
52    # New renderer extensions should be added with add_renderer_extension().
53    # If necessary the extensions list can be reset with
54    # init_renderer_extensions().
55    
56    _renderer_extensions = []
57    
58    def add_renderer_extension(layer_class, function):
59        """Add a renderer extension for the layer class layer_class
60    
61        When an instance of layer_class is to be drawn by the renderer the
62        renderer will call function with the renderer and the layer_class
63        instance as arguments. Since drawing is done incrementally, the
64        function should return an iterable. The easiest way is to simply
65        implement the draw_function as a generator and to yield True in
66        suitable places, or to return the empty tuple if it's not possible
67        to do the rendering in incrementally.
68        """
69        _renderer_extensions.append((layer_class, function))
70    
71    def init_renderer_extensions():
72        """(Re)initialize the list of renderer extensions
73    
74        Calling this function outside of the test suite is probably not
75        useful.
76        """
77        del _renderer_extensions[:]
78    
79    
80    #
81    #       Base Renderer
82    #
83    
84  class BaseRenderer:  class BaseRenderer:
85    
86      """Basic Renderer Infrastructure for Thuban Maps      """Basic Renderer Infrastructure for Thuban Maps
# Line 158  class BaseRenderer: Line 206  class BaseRenderer:
206                      self.draw_raster_layer(layer)                      self.draw_raster_layer(layer)
207                      seenRaster = True                      seenRaster = True
208                      yield True                      yield True
209                    else:
210                        # look it up in the renderer extensions
211                        for cls, func in _renderer_extensions:
212                            if isinstance(layer, cls):
213                                for i in func(self, layer):
214                                    yield True
215                                break
216                        else:
217                            # No renderer found. Print a message about it
218                            print >>sys.stderr, ("Drawing layer %r not supported"
219                                                 % layer)
220                yield True
221    
222          self.draw_label_layer(self.map.LabelLayer())          self.draw_label_layer(self.map.LabelLayer())
223          yield False          yield False
# Line 184  class BaseRenderer: Line 244  class BaseRenderer:
244          defaultGroup = lc.GetDefaultGroup()          defaultGroup = lc.GetDefaultGroup()
245          table = layer.ShapeStore().Table()          table = layer.ShapeStore().Table()
246    
247            if lc.GetNumGroups() == 0:
248                # There's only the default group, so we can pretend that
249                # there is no field to classifiy on which makes things
250                # faster since we don't need the attribute information at
251                # all.
252                field = None
253    
254          # Determine which render function to use.          # Determine which render function to use.
255          useraw, draw_func, draw_func_param = self.low_level_renderer(layer)          useraw, draw_func, draw_func_param = self.low_level_renderer(layer)
256    
257            #
258          # Iterate through all shapes that have to be drawn.          # Iterate through all shapes that have to be drawn.
259            #
260    
261            # Count the shapes drawn so that we can yield every few hundred
262            # shapes
263          count = 0          count = 0
264    
265            # Cache the tools (pens and brushes) for the classification
266            # groups. This is a mapping from the group's ids to the a tuple
267            # (pen, brush)
268            tool_cache = {}
269    
270          for shape in self.layer_shapes(layer):          for shape in self.layer_shapes(layer):
271              count += 1              count += 1
272              if field is None:              if field is None:
273                  group = defaultGroup                  group = defaultGroup
274              else:              else:
275                  record = table.ReadRowAsDict(shape.ShapeID())                  value = table.ReadValue(shape.ShapeID(), field)
276                  assert record is not None                  group = lc.FindGroup(value)
                 group = lc.FindGroup(record[field])  
277    
278              if not group.IsVisible():              if not group.IsVisible():
279                  continue                  continue
280    
281              # don't recreate new objects if they are the same as before              try:
282              if group is not old_group:                  pen, brush = tool_cache[id(group)]
283                  old_group = group              except KeyError:
284                    pen, brush = tool_cache[id(group)] \
285                  prop = group.GetProperties()                               = self.tools_for_property(group.GetProperties())
   
                 if prop != old_prop:  
                     pen, brush = self.tools_for_property(prop)  
286    
287              if useraw:              if useraw:
288                  data = shape.RawData()                  data = shape.RawData()
# Line 408  class BaseRenderer: Line 482  class BaseRenderer:
482              # better.              # better.
483              traceback.print_exc()              traceback.print_exc()
484          else:          else:
485              self.draw_raster_data(data)              self.draw_raster_data(data, "BMP")
486    
487      def draw_raster_data(self, data):      def draw_raster_data(self, data, format="BMP"):
488          """Draw the raster image in data onto the DC          """Draw the raster image in data onto the DC
489    
490          The raster image data is a string holding the data in BMP          The raster image data is a string holding the data in the format
491          format. The data is exactly the size of the dc and covers it          indicated by the format parameter. The image is assumed to be
492          completely.          exactly the size of the dc and to cover it completely.
493    
494            The format parameter is a string with the name of the format.
495            The following format names should be used:
496    
497              'BMP' -- Windows Bitmap
498              'JPEG' -- Jpeg
499    
500            The default format is 'bmp'.
501    
502          This method has to be implemented by derived classes.          This method has to be implemented by derived classes. The
503            implementation in the derived class should try to support at
504            least the formats specified above and may support more.
505          """          """
506          raise NotImplementedError          raise NotImplementedError
507    

Legend:
Removed from v.1866  
changed lines
  Added in v.1926

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26