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

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

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

revision 1552 by bh, Wed Aug 6 17:21:32 2003 UTC revision 1937 by bh, Tue Nov 11 18:16:42 2003 UTC
# Line 7  Line 7 
7  # This program is free software under the GPL (>=v2)  # This program is free software under the GPL (>=v2)
8  # Read the file COPYING coming with Thuban for details.  # Read the file COPYING coming with Thuban for details.
9    
10    from __future__ import generators
11    
12  __version__ = "$Revision$"  __version__ = "$Revision$"
13    # $Source$
14    # $Id$
15    
16  import cStringIO  import cStringIO
17    
# Line 16  from Thuban import _ Line 20  from Thuban import _
20  from wxPython.wx import wxPoint, wxRect, wxPen, wxBrush, wxFont, \  from wxPython.wx import wxPoint, wxRect, wxPen, wxBrush, wxFont, \
21      wxTRANSPARENT_PEN, wxTRANSPARENT_BRUSH, \      wxTRANSPARENT_PEN, wxTRANSPARENT_BRUSH, \
22      wxBLACK_PEN, wxBLACK, wxSOLID, wxCROSS_HATCH, wxSWISS, wxNORMAL, \      wxBLACK_PEN, wxBLACK, wxSOLID, wxCROSS_HATCH, wxSWISS, wxNORMAL, \
23      wxBitmapFromImage, wxImageFromStream, wxBITMAP_TYPE_BMP      wxBitmapFromImage, wxImageFromStream, wxBITMAP_TYPE_BMP, wxBITMAP_TYPE_JPEG
24    
25  from wxproj import draw_polygon_shape, draw_polygon_init  from wxproj import draw_polygon_shape, draw_polygon_init
26    
# Line 24  from Thuban.UI.common import Color2wxCol Line 28  from Thuban.UI.common import Color2wxCol
28  from Thuban.UI.classifier import ClassDataPreviewer  from Thuban.UI.classifier import ClassDataPreviewer
29  from Thuban.UI.scalebar import ScaleBar  from Thuban.UI.scalebar import ScaleBar
30    
31  from Thuban.Model.data import SHAPETYPE_POLYGON, SHAPETYPE_ARC, SHAPETYPE_POINT  from Thuban.Model.data import SHAPETYPE_POLYGON, SHAPETYPE_ARC, \
32         SHAPETYPE_POINT, RAW_SHAPEFILE
33    
34  from Thuban.Model.color import Transparent  from Thuban.Model.color import Transparent
35  import Thuban.Model.resource  import Thuban.Model.resource
36    
37  from baserenderer import BaseRenderer  from baserenderer import BaseRenderer
38    
39    
40    # Map the strings used for the format parameter of the draw_raster_data
41    # method to the appropriate wxWindows constants
42    raster_format_map = {
43        "BMP": wxBITMAP_TYPE_BMP,
44        "JPEG": wxBITMAP_TYPE_JPEG,
45        }
46    
47  class MapRenderer(BaseRenderer):  class MapRenderer(BaseRenderer):
48    
49      """Class to render a map onto a wxDC"""      """Class to render a map onto a wxDC"""
# Line 38  class MapRenderer(BaseRenderer): Line 51  class MapRenderer(BaseRenderer):
51      TRANSPARENT_PEN = wxTRANSPARENT_PEN      TRANSPARENT_PEN = wxTRANSPARENT_PEN
52      TRANSPARENT_BRUSH = wxTRANSPARENT_BRUSH      TRANSPARENT_BRUSH = wxTRANSPARENT_BRUSH
53    
54      make_point = wxPoint      def make_point(self, x, y):
55            return wxPoint(int(round(x)), int(round(y)))
56    
57      def tools_for_property(self, prop):      def tools_for_property(self, prop):
58          fill = prop.GetFill()          fill = prop.GetFill()
# Line 57  class MapRenderer(BaseRenderer): Line 71  class MapRenderer(BaseRenderer):
71      def low_level_renderer(self, layer):      def low_level_renderer(self, layer):
72          """Override inherited method to provide more efficient renderers          """Override inherited method to provide more efficient renderers
73    
74          For point shapes, return self.draw_point_shape and layer just as          If the underlying data format is not a shapefile or the layer
75          the base class method. For arc and polygon use the more          contains points shapes, simply use what the inherited method
76          efficient wxproj.draw_polygon_shape and its corresponding          returns.
77          parameter created with wxproj.draw_polygon_init.  
78            Otherwise, i.e. for arc and polygon use the more efficient
79            wxproj.draw_polygon_shape and its corresponding parameter
80            created with wxproj.draw_polygon_init.
81          """          """
82          shapetype = layer.ShapeType()          if (layer.ShapeStore().RawShapeFormat() == RAW_SHAPEFILE
83          if shapetype == SHAPETYPE_POINT:              and layer.ShapeType() in (SHAPETYPE_ARC, SHAPETYPE_POLYGON)):
             func = self.draw_point_shape  
             param = layer  
         else:  
84              offx, offy = self.offset              offx, offy = self.offset
85              param = draw_polygon_init(layer.ShapeStore().Shapefile(), self.dc,              return (True, draw_polygon_shape,
86                                        self.map.projection,                      draw_polygon_init(layer.ShapeStore().Shapefile(),
87                                          self.dc, self.map.projection,
88                                        layer.projection,                                        layer.projection,
89                                        self.scale, -self.scale,                                        self.scale, -self.scale, offx, offy))
90                                        offx, offy)          else:
91              func = draw_polygon_shape              return BaseRenderer.low_level_renderer(self, layer)
         return func, param  
92    
93      def label_font(self):      def label_font(self):
94          return wxFont(self.resolution * 10, wxSWISS, wxNORMAL, wxNORMAL)          return wxFont(int(round(self.resolution * 10)), wxSWISS, wxNORMAL,
95                          wxNORMAL)
96    
97      def draw_raster_data(self, data):      def draw_raster_data(self, data, format = 'BMP'):
98          stream = cStringIO.StringIO(data)          stream = cStringIO.StringIO(data)
99          image = wxImageFromStream(stream, wxBITMAP_TYPE_BMP)          image = wxImageFromStream(stream, raster_format_map[format])
100          bitmap = wxBitmapFromImage(image)          bitmap = wxBitmapFromImage(image)
101          self.dc.DrawBitmap(bitmap, 0, 0)          self.dc.DrawBitmap(bitmap, 0, 0)
102    
# Line 91  class ScreenRenderer(MapRenderer): Line 106  class ScreenRenderer(MapRenderer):
106      # On the screen we want to see only visible layers by default      # On the screen we want to see only visible layers by default
107      honor_visibility = 1      honor_visibility = 1
108    
109      def RenderMap(self, map, region, selected_layer, selected_shapes):      def RenderMap(self, selected_layer, selected_shapes):
110          """Render the map.          """Render the map.
111    
112          Only the given region (a tuple in window coordinates as returned          Only the given region (a tuple in window coordinates as returned
# Line 99  class ScreenRenderer(MapRenderer): Line 114  class ScreenRenderer(MapRenderer):
114          shapes given by the ids in selected_shapes in the          shapes given by the ids in selected_shapes in the
115          selected_layer.          selected_layer.
116          """          """
         self.update_region = region  
117          self.selected_layer = selected_layer          self.selected_layer = selected_layer
118          self.selected_shapes = selected_shapes          self.selected_shapes = selected_shapes
119          self.render_map(map)          self.render_map()
120    
121      def draw_shape_layer(self, layer):      def RenderMapIncrementally(self):
122          MapRenderer.draw_shape_layer(self, layer)          """Render the map.
         if layer is self.selected_layer and self.selected_shapes:  
             pen = wxPen(wxBLACK, 3, wxSOLID)  
             brush = wxBrush(wxBLACK, wxCROSS_HATCH)  
   
             shapetype = layer.ShapeType()  
             func, param = self.low_level_renderer(layer)  
             args = (pen, brush)  
             for index in self.selected_shapes:  
                 func(param, index, *args)  
123    
124      def layer_ids(self, layer):          Only the given region (a tuple in window coordinates as returned
125            by a wxrect's asTuple method) needs to be redrawn. Highlight the
126            shapes given by the ids in selected_shapes in the
127            selected_layer.
128            """
129            return self.render_map_incrementally()
130    
131        def draw_selection_incrementally(self, layer, selected_shapes):
132            pen = wxPen(wxBLACK, 3, wxSOLID)
133            brush = wxBrush(wxBLACK, wxCROSS_HATCH)
134    
135            shapetype = layer.ShapeType()
136            useraw, func, param = self.low_level_renderer(layer)
137            args = (pen, brush)
138            count = 0
139            for index in selected_shapes:
140                count += 1
141                shape = layer.Shape(index)
142                if useraw:
143                    data = shape.RawData()
144                else:
145                    data = shape.Points()
146                func(param, data, *args)
147                if count % 500 == 0:
148                    yield True
149    
150        def layer_shapes(self, layer):
151          """Return the shapeids covered by the region that has to be redrawn          """Return the shapeids covered by the region that has to be redrawn
152    
153          Call the layer's ShapesInRegion method to determine the ids so          Call the layer's ShapesInRegion method to determine the ids so
# Line 137  class ScreenRenderer(MapRenderer): Line 168  class ScreenRenderer(MapRenderer):
168          offx, offy = self.offset          offx, offy = self.offset
169          xs = []          xs = []
170          ys = []          ys = []
171          x, y, width, height = self.update_region          x, y, width, height = self.region
172          for winx, winy in ((x, y), (x + width, y),          for winx, winy in ((x, y), (x + width, y),
173                             (x + width, y + height), (x, y + height)):                             (x + width, y + height), (x, y + height)):
174              px = (winx - offx) / scale              px = (winx - offx) / scale
# Line 158  class ExportRenderer(ScreenRenderer): Line 189  class ExportRenderer(ScreenRenderer):
189    
190      honor_visibility = 1      honor_visibility = 1
191    
192      def RenderMap(self, map, region, mapregion,      def __init__(self, *args, **kw):
193                    selected_layer, selected_shapes ):          """Initialize the ExportRenderer.
194    
195            In addition to all parameters of the the ScreenRender
196            constructor, this class requires and additional keyword argument
197            destination_region with a tuple (minx, miny, maxx, maxy) giving
198            the region in dc coordinates which is to contain the map.
199            """
200            self.destination_region = kw["destination_region"]
201            del kw["destination_region"]
202            ScreenRenderer.__init__(self, *args, **kw)
203    
204        def RenderMap(self, selected_layer, selected_shapes):
205          """Render the map.          """Render the map.
206    
207          The rendering device has been specified during initialisation.          The rendering device has been specified during initialisation.
208          The device border distance was set in Thuban.UI.view.OutputTranform().          The device border distance was set in
209            Thuban.UI.viewport.output_transform().
210    
211          RenderMap renders a frame set (one page frame, one around          RenderMap renders a frame set (one page frame, one around
212          legend/scalebar and one around the map), the map, the legend and the          legend/scalebar and one around the map), the map, the legend and
213          scalebar on the given DC. The map is rendered with the region displayed          the scalebar on the given DC. The map is rendered with the
214          in the canvas view, centered on the area available for map display.          region displayed in the canvas view, centered on the area
215            available for map display.
216          """          """
217    
         self.update_region = region  
218          self.selected_layer = selected_layer          self.selected_layer = selected_layer
219          self.selected_shapes = selected_shapes          self.selected_shapes = selected_shapes
220    
221          # Get some dimensions          # Get some dimensions
222          llx, lly, urx, ury = region          llx, lly, urx, ury = self.region
223          self.mapregion = mapregion          mminx, mminy, mmaxx, mmaxy = self.destination_region
         mminx, mminy, mmaxx, mmaxy = self.mapregion  
224    
225          # Manipulate the offset to position the map          # Manipulate the offset to position the map
226          offx, offy = self.offset          offx, offy = self.offset
# Line 199  class ExportRenderer(ScreenRenderer): Line 241  class ExportRenderer(ScreenRenderer):
241          self.dc.DestroyClippingRegion()          self.dc.DestroyClippingRegion()
242          self.dc.SetClippingRegion(mminx+self.shiftx, mminy+self.shifty,          self.dc.SetClippingRegion(mminx+self.shiftx, mminy+self.shifty,
243                                    urx, ury)                                    urx, ury)
244          self.render_map(map)          self.render_map()
245          self.dc.EndDrawing()          self.dc.EndDrawing()
246    
247          # Draw the rest (frames, legend, scalebar)          # Draw the rest (frames, legend, scalebar)
# Line 210  class ExportRenderer(ScreenRenderer): Line 252  class ExportRenderer(ScreenRenderer):
252          font = wxFont(self.resolution * 10, wxSWISS, wxNORMAL, wxNORMAL)          font = wxFont(self.resolution * 10, wxSWISS, wxNORMAL, wxNORMAL)
253          self.dc.SetFont(font)          self.dc.SetFont(font)
254    
255          self.render_frame(region)          self.render_frame()
256          self.render_legend(map)          self.render_legend()
257          self.render_scalebar(map)          self.render_scalebar()
258          self.dc.EndDrawing()          self.dc.EndDrawing()
259    
260      def render_frame(self, region):      def render_frame(self):
261          """Render the frames for map and legend/scalebar."""          """Render the frames for map and legend/scalebar."""
262    
263          dc = self.dc          dc = self.dc
# Line 224  class ExportRenderer(ScreenRenderer): Line 266  class ExportRenderer(ScreenRenderer):
266    
267          # Dimension stuff          # Dimension stuff
268          width, height = dc.GetSizeTuple()          width, height = dc.GetSizeTuple()
269          mminx, mminy, mmaxx, mmaxy = self.mapregion          mminx, mminy, mmaxx, mmaxy = self.destination_region
270    
271          # Page Frame          # Page Frame
272          dc.DrawRectangle(15,15,width-30, (mmaxy-mminy)+10)          dc.DrawRectangle(15,15,width-30, (mmaxy-mminy)+10)
273    
274          # Map Frame          # Map Frame
275          llx, lly, urx, ury = region          llx, lly, urx, ury = self.region
276          dc.DrawRectangle(mminx + self.shiftx, mminy + self.shifty, urx, ury)          dc.DrawRectangle(mminx + self.shiftx, mminy + self.shifty, urx, ury)
277    
278          # Legend Frame          # Legend Frame
# Line 240  class ExportRenderer(ScreenRenderer): Line 282  class ExportRenderer(ScreenRenderer):
282          dc.SetClippingRegion(mmaxx+10,mminy,          dc.SetClippingRegion(mmaxx+10,mminy,
283                               (width-20) - (mmaxx+10), mmaxy-mminy)                               (width-20) - (mmaxx+10), mmaxy-mminy)
284    
285      def render_legend(self, map):      def render_legend(self):
286          """Render the legend on the Map."""          """Render the legend on the Map."""
287    
288          previewer = ClassDataPreviewer()          previewer = ClassDataPreviewer()
# Line 250  class ExportRenderer(ScreenRenderer): Line 292  class ExportRenderer(ScreenRenderer):
292    
293          # Dimension stuff          # Dimension stuff
294          width, height = dc.GetSizeTuple()          width, height = dc.GetSizeTuple()
295          mminx, mminy, mmaxx, mmaxy = self.mapregion          mminx, mminy, mmaxx, mmaxy = self.destination_region
296          textwidth, textheight = dc.GetTextExtent("0")          textwidth, textheight = dc.GetTextExtent("0")
297          iconwidth  = textheight          iconwidth  = textheight
298          iconheight = textheight          iconheight = textheight
# Line 262  class ExportRenderer(ScreenRenderer): Line 304  class ExportRenderer(ScreenRenderer):
304    
305          # Render the legend          # Render the legend
306          dc.SetTextForeground(wxBLACK)          dc.SetTextForeground(wxBLACK)
307          if map.HasLayers():          if self.map.HasLayers():
308              layers = map.Layers()              layers = self.map.Layers()[:]
309              layers.reverse()              layers.reverse()
310              for l in layers:              for l in layers:
311                  if l.Visible():                  if l.Visible():
# Line 284  class ExportRenderer(ScreenRenderer): Line 326  class ExportRenderer(ScreenRenderer):
326                                              posx+2*dx+iconwidth, posy)                                              posx+2*dx+iconwidth, posy)
327                                  posy+=stepy                                  posy+=stepy
328    
329      def render_scalebar(self, map):      def render_scalebar(self):
330          """Render the scalebar."""          """Render the scalebar."""
331    
332          scalebar = ScaleBar(map)          scalebar = ScaleBar(self.map)
333    
334          # Dimension stuff          # Dimension stuff
335          width, height = self.dc.GetSizeTuple()          width, height = self.dc.GetSizeTuple()
336          mminx, mminy, mmaxx, mmaxy = self.mapregion          mminx, mminy, mmaxx, mmaxy = self.destination_region
337    
338          # Render the scalebar          # Render the scalebar
339          scalebar.DrawScaleBar(self.scale, self.dc,          scalebar.DrawScaleBar(self.scale, self.dc,

Legend:
Removed from v.1552  
changed lines
  Added in v.1937

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26