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

Legend:
Removed from v.76  
changed lines
  Added in v.686

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26