/[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 6 by bh, Tue Aug 28 15:41:52 2001 UTC revision 882 by jonathan, Fri May 9 16:34:28 2003 UTC
# Line 1  Line 1 
1  # Copyright (c) 2001 by Intevation GmbH  # Copyright (c) 2001, 2002, 2003 by Intevation GmbH
2  # Authors:  # Authors:
3  # Bernhard Herzog <[email protected]>  # Bernhard Herzog <[email protected]>
4    # Jonathan Coles <[email protected]>
5  #  #
6  # This program is free software under the GPL (>=v2)  # This program is free software under the GPL (>=v2)
7  # Read the file COPYING coming with Thuban for details.  # Read the file COPYING coming with Thuban for details.
8    
9  __version__ = "$Revision$"  __version__ = "$Revision$"
10    
11  from wxPython.wx import wxPoint, wxColour, wxPen, wxBrush, wxFont, \  from Thuban import _
12    
13    from wxPython.wx import wxPoint, wxPen, wxBrush, wxFont, \
14       wxTRANSPARENT_PEN, wxTRANSPARENT_BRUSH, \       wxTRANSPARENT_PEN, wxTRANSPARENT_BRUSH, \
15       wxBLACK, wxSOLID, wxCROSS_HATCH, wxSWISS, wxNORMAL       wxBLACK, wxSOLID, wxCROSS_HATCH, wxSWISS, wxNORMAL
16    
17  from wxproj import draw_polygon_shape  from wxproj import draw_polygon_shape, draw_polygon_init
18    
19    from Thuban.UI.common import Color2wxColour
20    
21  from Thuban.Model.layer import SHAPETYPE_POLYGON, SHAPETYPE_ARC, \  from Thuban.Model.layer import SHAPETYPE_POLYGON, SHAPETYPE_ARC, \
22       SHAPETYPE_POINT       SHAPETYPE_POINT
23  from Thuban.Model.label import ALIGN_CENTER, ALIGN_TOP, ALIGN_BOTTOM, \  from Thuban.Model.label import ALIGN_CENTER, ALIGN_TOP, ALIGN_BOTTOM, \
24       ALIGN_LEFT, ALIGN_RIGHT, ALIGN_BASELINE       ALIGN_LEFT, ALIGN_RIGHT, ALIGN_BASELINE
25    
26    from Thuban.Model.classification import Classification
27    from Thuban.Model.color import Color
28    
29  class MapRenderer:  class MapRenderer:
30    
# Line 41  class MapRenderer: Line 48  class MapRenderer:
48                  the renderer's default.                  the renderer's default.
49          """          """
50          # resolution in pixel/inch          # resolution in pixel/inch
51    
52          self.dc = dc          self.dc = dc
53          self.scale = scale          self.scale = scale
54          self.offset = offset          self.offset = offset
# Line 63  class MapRenderer: Line 71  class MapRenderer:
71          scale = self.scale          scale = self.scale
72          offx, offy = self.offset          offx, offy = self.offset
73    
         fill = layer.fill  
         if fill is None:  
             brush = wxTRANSPARENT_BRUSH  
         else:  
             color = wxColour(fill.red * 255,  
                              fill.green * 255,  
                              fill.blue * 255)  
             brush = wxBrush(color, wxSOLID)  
         stroke = layer.stroke  
         if stroke is None:  
             pen = wxTRANSPARENT_PEN  
         else:  
             color = wxColour(stroke.red * 255,  
                              stroke.green * 255,  
                              stroke.blue * 255)  
             pen = wxPen(color, 1, wxSOLID)  
   
74          map_proj = self.map.projection          map_proj = self.map.projection
75          layer_proj = layer.projection          layer_proj = layer.projection
76    
77          shapetype = layer.ShapeType()          shapetype = layer.ShapeType()
78    
79          if shapetype == SHAPETYPE_POLYGON:          brush = wxTRANSPARENT_BRUSH
80              for i in range(layer.NumShapes()):          pen   = wxTRANSPARENT_PEN
81                  self.draw_polygon_shape(layer, i, pen, brush)  
82            old_prop = None
83            old_group = None
84            lc = layer.GetClassification()
85            field = lc.GetField()
86            defaultGroup = lc.GetDefaultGroup()
87    
88    
89            if shapetype != SHAPETYPE_POINT:
90                polygon_render_param = self.polygon_render_param(layer)
91    
92            if shapetype == SHAPETYPE_POINT:
93                draw_func = lambda i: \
94                       self.draw_point_shape(layer, i)
95          else:          else:
96              self.dc.SetBrush(brush)              draw_func = lambda i: \
97              self.dc.SetPen(pen)                     self.draw_polygon_shape(polygon_render_param, i, pen, brush)
98              if shapetype == SHAPETYPE_ARC:              
99                  f = self.draw_arc_shape          for i in self.layer_ids(layer):
100              elif shapetype == SHAPETYPE_POINT:  
101                  f = self.draw_point_shape              if field is None:
102              for i in range(layer.NumShapes()):                  group = defaultGroup
103                  f(layer, i)              else:
104                    record = layer.table.ReadRowAsDict(i)
105      def draw_polygon_shape(self, layer, index, pen, brush):                  assert record is not None
106          offx, offy = self.offset                          group = lc.FindGroup(record[field])
107          draw_polygon_shape(layer.shapefile.cobject(), index,  
108                             self.dc, pen, brush,  
109                             self.map.projection, layer.projection,              if not group.IsVisible():
110                             self.scale, -self.scale, offx, offy)                  continue
111    
112    
113                # don't recreate new objects if they are the same as before
114                if group is not old_group:
115                    old_group = group
116    
117                    prop = group.GetProperties()
118    
119                    if prop != old_prop:
120                        old_prop = prop
121    
122                        if shapetype == SHAPETYPE_ARC:
123                            fill = Color.Transparent
124                        else:
125                            fill = prop.GetFill()
126    
127    
128                        if fill is Color.Transparent:
129                            brush = wxTRANSPARENT_BRUSH
130                        else:
131                            color = Color2wxColour(fill)
132                            brush = wxBrush(color, wxSOLID)
133    
134                        stroke = prop.GetLineColor()
135                        stroke_width = prop.GetLineWidth()
136                        if stroke is Color.Transparent:
137                            pen = wxTRANSPARENT_PEN
138                        else:
139                            color = Color2wxColour(stroke)
140                            pen = wxPen(color, stroke_width, wxSOLID)
141    
142                        if shapetype == SHAPETYPE_POINT:
143                            self.dc.SetBrush(brush)
144                            self.dc.SetPen(pen)
145    
146                draw_func(i)
147    
148        def layer_ids(self, layer):
149            """Return the shape ids of the given layer that have to be drawn.
150    
151            The default implementation simply returns all ids in the layer.
152            Override in derived classes to be more precise.
153            """
154            return range(layer.NumShapes())
155    
156        def polygon_render_param(self, layer):
157            """Return the low-lever render parameter for the layer"""
158            offx, offy = self.offset
159            return draw_polygon_init(layer.shapefile, self.dc,
160                                     self.map.projection,
161                                     layer.projection,
162                                     self.scale, -self.scale,
163                                     offx, offy)
164    
165        def draw_polygon_shape(self, draw_polygon_info, index, pen, brush):
166            draw_polygon_shape(draw_polygon_info, index, pen, brush)
167    
168      def projected_points(self, layer, index):      def projected_points(self, layer, index):
169          proj = self.map.projection          proj = self.map.GetProjection()
170          if proj is not None:          if proj is not None:
171              forward = proj.Forward              forward = proj.Forward
172          else:          else:
173              forward = None              forward = None
174          proj = layer.projection          proj = layer.GetProjection()
175          if proj is not None:          if proj is not None:
176              inverse = proj.Inverse              inverse = proj.Inverse
177          else:          else:
# Line 134  class MapRenderer: Line 194  class MapRenderer:
194          self.dc.DrawLines(points)          self.dc.DrawLines(points)
195    
196      def draw_point_shape(self, layer, index):      def draw_point_shape(self, layer, index):
197          p = self.projected_points(layer, index)[0]          pp = self.projected_points(layer, index)
198    
199            if len(pp) == 0: return # ignore Null Shapes which have no points
200    
201            p = pp[0]
202          radius = self.resolution * 5          radius = self.resolution * 5
203          self.dc.DrawEllipse(p.x - radius, p.y - radius, 2*radius, 2*radius)          self.dc.DrawEllipse(p.x - radius, p.y - radius, 2*radius, 2*radius)
204    
# Line 182  class ScreenRenderer(MapRenderer): Line 246  class ScreenRenderer(MapRenderer):
246      # On the screen we want to see only visible layers by default      # On the screen we want to see only visible layers by default
247      honor_visibility = 1      honor_visibility = 1
248            
249      def RenderMap(self, map, selected_layer, selected_shape):      def RenderMap(self, map, region, selected_layer, selected_shapes):
250            """Render the map.
251    
252            Only the given region (a tuple in window coordinates as returned
253            by a wxrect's asTuple method) needs to be redrawn. Highlight the
254            shapes given by the ids in selected_shapes in the
255            selected_layer.
256            """
257            self.update_region = region
258          self.selected_layer = selected_layer          self.selected_layer = selected_layer
259          self.selected_shape = selected_shape          self.selected_shapes = selected_shapes
260          self.render_map(map)          self.render_map(map)
261    
262      def draw_shape_layer(self, layer):      def draw_shape_layer(self, layer):
263          MapRenderer.draw_shape_layer(self, layer)          MapRenderer.draw_shape_layer(self, layer)
264          if layer is self.selected_layer and self.selected_shape is not None:          if layer is self.selected_layer and self.selected_shapes:
265              pen = wxPen(wxBLACK, 3, wxSOLID)              pen = wxPen(wxBLACK, 3, wxSOLID)
266              brush = wxBrush(wxBLACK, wxCROSS_HATCH)              brush = wxBrush(wxBLACK, wxCROSS_HATCH)
267                
268              shapetype = layer.ShapeType()              shapetype = layer.ShapeType()
             index = self.selected_shape  
269              if shapetype == SHAPETYPE_POLYGON:              if shapetype == SHAPETYPE_POLYGON:
270                  self.draw_polygon_shape(layer, index, pen, brush)                  offx, offy = self.offset
271              else:                  renderparam = self.polygon_render_param(layer)
272                    func = self.draw_polygon_shape
273                    args = (pen, brush)
274                elif shapetype == SHAPETYPE_ARC:
275                    renderparam = self.polygon_render_param(layer)
276                    func = self.draw_polygon_shape
277                    args = (pen, None)
278                elif shapetype == SHAPETYPE_POINT:
279                    renderparam = layer
280                  self.dc.SetBrush(brush)                  self.dc.SetBrush(brush)
281                  self.dc.SetPen(pen)                  self.dc.SetPen(pen)
282                  if shapetype == SHAPETYPE_ARC:                  func = self.draw_point_shape
283                      f = self.draw_arc_shape                  args = ()
284                  elif shapetype == SHAPETYPE_POINT:              else:
285                      f = self.draw_point_shape                  raise TypeError(_("Unhandled shape type %s") % shapetype)
286                  f(layer, index)  
287                for index in self.selected_shapes:
288                    func(renderparam, index, *args)
289    
290    
291        def layer_ids(self, layer):
292            """Return the shapeids covered by the region that has to be redrawn
293    
294            Call the layer's ShapesInRegion method to determine the ids so
295            that it can use the quadtree.
296            """
297            # FIXME: the quad-tree should be built from the projected
298            # coordinates not the lat-long ones because it's not trivial to
299            # determine an appropriate rectangle in lat-long for a given
300            # rectangle in projected coordinates which we have to start from
301            # here.
302            proj = self.map.projection
303            if proj is not None:
304                inverse = proj.Inverse
305            else:
306                inverse = None
307    
308            scale = self.scale
309            offx, offy = self.offset
310            xs = []
311            ys = []
312            x, y, width, height = self.update_region
313            for winx, winy in ((x, y), (x + width, y),
314                               (x + width, y + height), (x, y + height)):
315                px = (winx - offx) / scale
316                py = -(winy - offy) / scale
317                if inverse:
318                    px, py = inverse(px, py)
319                xs.append(px)
320                ys.append(py)
321            left = min(xs)
322            right = max(xs)
323            top = max(ys)
324            bottom = min(ys)
325    
326            return layer.ShapesInRegion((left, bottom, right, top))
327    
328    
329  class PrinterRender(MapRenderer):  class PrinterRender(MapRenderer):

Legend:
Removed from v.6  
changed lines
  Added in v.882

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26