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

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26