/[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 882 by jonathan, Fri May 9 16:34:28 2003 UTC revision 1219 by bh, Mon Jun 16 17:42:54 2003 UTC
# Line 2  Line 2 
2  # Authors:  # Authors:
3  # Bernhard Herzog <[email protected]>  # Bernhard Herzog <[email protected]>
4  # Jonathan Coles <[email protected]>  # Jonathan Coles <[email protected]>
5    # Frank Koormann <[email protected]>
6  #  #
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  __version__ = "$Revision$"  __version__ = "$Revision$"
11    
12    import cStringIO
13    
14  from Thuban import _  from Thuban import _
15    
16  from wxPython.wx import wxPoint, wxPen, wxBrush, wxFont, \  from wxPython.wx import wxMemoryDC, wxEmptyBitmap, \
17       wxTRANSPARENT_PEN, wxTRANSPARENT_BRUSH, \      wxPoint, wxRect, wxPen, wxBrush, wxFont, \
18       wxBLACK, wxSOLID, wxCROSS_HATCH, wxSWISS, wxNORMAL      wxTRANSPARENT_PEN, wxTRANSPARENT_BRUSH, \
19        wxBLACK_PEN, wxRED_PEN, wxBLACK, \
20        wxSOLID, wxCROSS_HATCH, wxSWISS, wxNORMAL, \
21        wxBitmap, wxImageFromBitmap, wxBitmapFromImage, \
22        wxImageFromStream, wxBITMAP_TYPE_BMP
23    
24  from wxproj import draw_polygon_shape, draw_polygon_init  from wxproj import draw_polygon_shape, draw_polygon_init
25    from gdalwarp import ProjectRasterFile
26    
27  from Thuban.UI.common import Color2wxColour  from Thuban.UI.common import Color2wxColour
28    from Thuban.UI.classifier import ClassDataPreviewer
29    from Thuban.UI.scalebar import ScaleBar
30    
31  from Thuban.Model.layer import SHAPETYPE_POLYGON, SHAPETYPE_ARC, \  from Thuban.Model.layer import Layer, RasterLayer, \
32       SHAPETYPE_POINT       SHAPETYPE_POLYGON, SHAPETYPE_ARC, SHAPETYPE_POINT
33  from Thuban.Model.label import ALIGN_CENTER, ALIGN_TOP, ALIGN_BOTTOM, \  from Thuban.Model.label import ALIGN_CENTER, ALIGN_TOP, ALIGN_BOTTOM, \
34       ALIGN_LEFT, ALIGN_RIGHT, ALIGN_BASELINE       ALIGN_LEFT, ALIGN_RIGHT, ALIGN_BASELINE
35    
36  from Thuban.Model.classification import Classification  from Thuban.Model.classification import Classification
37  from Thuban.Model.color import Color  from Thuban.Model.color import Color
38    import Thuban.Model.resource
39    
40  class MapRenderer:  class MapRenderer:
41    
# Line 60  class MapRenderer: Line 71  class MapRenderer:
71    
72      def render_map(self, map):      def render_map(self, map):
73          self.map = map          self.map = map
74            seenRaster = True
75    
76            if self.scale == 0:
77                return
78    
79            #
80            # This is only a good optimization if there is only one
81            # raster layer and the image covers the entire window (as
82            # it currently does). We note if there is a raster layer
83            # and only begin drawing layers once we have drawn it.
84            # That way we avoid drawing layers that won't be seen.
85            #
86            for layer in map.Layers():
87                if isinstance(layer, RasterLayer) and layer.Visible():
88                    seenRaster = False
89                    break
90    
91          for layer in map.Layers():          for layer in map.Layers():
92              # if honor_visibility is true, only draw visible layers,              # if honor_visibility is true, only draw visible layers,
93              # otherwise draw all layers              # otherwise draw all layers
94              if not self.honor_visibility or layer.Visible():              if not self.honor_visibility or layer.Visible():
95                  self.draw_shape_layer(layer)                  if isinstance(layer, Layer) and seenRaster:
96                        self.draw_shape_layer(layer)
97                    elif isinstance(layer, RasterLayer) \
98                        and Thuban.Model.resource.has_gdal_support():
99                        self.draw_raster_layer(layer)
100                        seenRaster = True
101    
102          self.draw_label_layer(map.LabelLayer())          self.draw_label_layer(map.LabelLayer())
103    
104      def draw_shape_layer(self, layer):      def draw_shape_layer(self, layer):
# Line 95  class MapRenderer: Line 129  class MapRenderer:
129          else:          else:
130              draw_func = lambda i: \              draw_func = lambda i: \
131                     self.draw_polygon_shape(polygon_render_param, i, pen, brush)                     self.draw_polygon_shape(polygon_render_param, i, pen, brush)
132                
133            table = layer.ShapeStore().Table()
134          for i in self.layer_ids(layer):          for i in self.layer_ids(layer):
135    
136              if field is None:              if field is None:
137                  group = defaultGroup                  group = defaultGroup
138              else:              else:
139                  record = layer.table.ReadRowAsDict(i)                  record = table.ReadRowAsDict(i)
140                  assert record is not None                  assert record is not None
141                  group = lc.FindGroup(record[field])                  group = lc.FindGroup(record[field])
142    
# Line 145  class MapRenderer: Line 180  class MapRenderer:
180    
181              draw_func(i)              draw_func(i)
182    
183        def draw_raster_layer(self, layer):
184            data = None
185            offx, offy = self.offset
186            width, height = self.dc.GetSizeTuple()
187    
188            inProj = ""
189            proj = layer.GetProjection()
190            if proj is not None:
191                for p in proj.GetAllParameters():
192                    inProj += "+" + p + " "
193    
194            outProj = ""
195            proj = self.map.GetProjection()
196            if proj is not None:
197                for p in proj.GetAllParameters():
198                    outProj += "+" + p + " "
199    
200            xmin = (0 - offx) / self.scale
201            ymin = (offy - height) / self.scale
202            xmax = (width - offx) / self.scale
203            ymax = (offy - 0) / self.scale
204    
205            try:
206                data = ProjectRasterFile(
207                    layer.GetImageFilename(),
208                    inProj,
209                    outProj,
210                    (xmin, ymin, xmax, ymax),
211                    "", (width, height))
212            except IOError, (strerr):
213                print strerr
214            except (AttributeError, ValueError):
215                pass
216            else:
217                if data is not None:
218                    stream = cStringIO.StringIO(data)
219                    image = wxImageFromStream(stream, wxBITMAP_TYPE_BMP)
220                    bitmap = wxBitmapFromImage(image)
221                    self.dc.BeginDrawing()
222                    self.dc.DrawBitmap(bitmap, 0, 0)
223                    self.dc.EndDrawing()
224    
225      def layer_ids(self, layer):      def layer_ids(self, layer):
226          """Return the shape ids of the given layer that have to be drawn.          """Return the shape ids of the given layer that have to be drawn.
227    
# Line 156  class MapRenderer: Line 233  class MapRenderer:
233      def polygon_render_param(self, layer):      def polygon_render_param(self, layer):
234          """Return the low-lever render parameter for the layer"""          """Return the low-lever render parameter for the layer"""
235          offx, offy = self.offset          offx, offy = self.offset
236          return draw_polygon_init(layer.shapefile, self.dc,          return draw_polygon_init(layer.ShapeStore().Shapefile(), self.dc,
237                                   self.map.projection,                                   self.map.projection,
238                                   layer.projection,                                   layer.projection,
239                                   self.scale, -self.scale,                                   self.scale, -self.scale,
# Line 326  class ScreenRenderer(MapRenderer): Line 403  class ScreenRenderer(MapRenderer):
403          return layer.ShapesInRegion((left, bottom, right, top))          return layer.ShapesInRegion((left, bottom, right, top))
404    
405    
406  class PrinterRender(MapRenderer):  class ExportRenderer(ScreenRenderer):
407    
408      # When printing we want to see all layers      honor_visibility = 1
     honor_visibility = 0  
   
     RenderMap = MapRenderer.render_map  
409            
410        def RenderMap(self, map, region, mapregion,
411                      selected_layer, selected_shapes ):
412            """Render the map.
413    
414            The rendering device has been specified during initialisation.
415            The device border distance was set in Thuban.UI.view.OutputTranform().
416            
417            RenderMap renders a frame set (one page frame, one around
418            legend/scalebar and one around the map), the map, the legend and the
419            scalebar on the given DC. The map is rendered with the region displayed
420            in the canvas view, centered on the area available for map display.
421            """
422            
423            self.update_region = region
424            self.selected_layer = selected_layer
425            self.selected_shapes = selected_shapes
426    
427            # Get some dimensions
428            llx, lly, urx, ury = region
429            self.mapregion = mapregion
430            mminx, mminy, mmaxx, mmaxy = self.mapregion
431    
432            # Manipulate the offset to position the map
433            offx, offy = self.offset
434            # 1. Shift to corner of map drawing area
435            offx = offx + mminx
436            offy = offy + mminy
437    
438            # 2. Center the map on the map drawing area:
439            # region identifies the region on the canvas view:
440            # center of map drawing area - half the size of region: rendering origin
441            self.shiftx = (mmaxx - mminx)*0.5 - (urx - llx)*0.5
442            self.shifty = (mmaxy - mminy)*0.5 - (ury - lly)*0.5
443    
444            self.offset = (offx+self.shiftx, offy+self.shifty)
445    
446            # Draw the map
447            self.dc.BeginDrawing()
448            self.dc.DestroyClippingRegion()
449            self.dc.SetClippingRegion(mminx+self.shiftx, mminy+self.shifty,
450                                      urx, ury)
451            self.render_map(map)
452            self.dc.EndDrawing()
453    
454            # Draw the rest (frames, legend, scalebar)
455            self.dc.BeginDrawing()
456            self.dc.DestroyClippingRegion()
457    
458            # Force the font for Legend drawing
459            font = wxFont(self.resolution * 10, wxSWISS, wxNORMAL, wxNORMAL)
460            self.dc.SetFont(font)
461    
462            self.render_frame(region)
463            self.render_legend(map)
464            self.render_scalebar(map)
465            self.dc.EndDrawing()
466    
467        def render_frame(self, region):
468            """Render the frames for map and legend/scalebar."""
469    
470            dc = self.dc
471            dc.SetPen(wxBLACK_PEN)
472            dc.SetBrush(wxTRANSPARENT_BRUSH)
473    
474            # Dimension stuff
475            width, height = dc.GetSizeTuple()
476            mminx, mminy, mmaxx, mmaxy = self.mapregion
477    
478            # Page Frame
479            dc.DrawRectangle(15,15,width-30, (mmaxy-mminy)+10)
480            
481            # Map Frame
482            llx, lly, urx, ury = region
483            dc.DrawRectangle(mminx + self.shiftx, mminy + self.shifty, urx, ury)
484            
485            # Legend Frame
486            dc.DrawRectangle(mmaxx+10,mminy,(width-20) - (mmaxx+10), mmaxy-mminy)
487    
488            dc.DestroyClippingRegion()
489            dc.SetClippingRegion(mmaxx+10,mminy,
490                                 (width-20) - (mmaxx+10), mmaxy-mminy)
491    
492        def render_legend(self, map):
493            """Render the legend on the Map."""
494    
495            previewer = ClassDataPreviewer()
496            dc = self.dc
497            dc.SetPen(wxBLACK_PEN)
498            dc.SetBrush(wxTRANSPARENT_BRUSH)
499    
500            # Dimension stuff
501            width, height = dc.GetSizeTuple()
502            mminx, mminy, mmaxx, mmaxy = self.mapregion
503            textwidth, textheight = dc.GetTextExtent("0")
504            iconwidth  = textheight
505            iconheight = textheight
506            stepy = textheight+3
507            dx = 10
508            posx = mmaxx + 10 + 5   # 10 pix distance mapframe/legend frame,
509                                    # 5 pix inside legend frame
510            posy = mminy + 5        # 5 pix inside legend frame
511            
512            # Render the legend
513            dc.SetTextForeground(wxBLACK)
514            if map.HasLayers():
515                for l in map.Layers():
516                    if l.Visible():
517                        # Render title
518                        dc.DrawText(l.Title(), posx, posy)
519                        posy+=stepy
520                        # Render classification
521                        clazz = l.GetClassification()
522                        shapeType = l.ShapeType()
523                        for g in clazz:
524                            if g.IsVisible():
525                                previewer.Draw(dc,
526                                    wxRect(posx+dx, posy, iconwidth, iconheight),
527                                    g.GetProperties(), shapeType)
528                                dc.DrawText(g.GetDisplayText(),
529                                            posx+2*dx+iconwidth, posy)
530                                posy+=stepy
531            
532        def render_scalebar(self, map):
533            """Render the scalebar."""
534    
535            scalebar = ScaleBar(map)
536    
537            # Dimension stuff
538            width, height = self.dc.GetSizeTuple()
539            mminx, mminy, mmaxx, mmaxy = self.mapregion
540          
541            # Render the scalebar
542            scalebar.DrawScaleBar(self.scale, self.dc,
543                                 (mmaxx+10+5, mmaxy-25),
544                                 ((width-15-5) - (mmaxx+10+5),20)
545                                )
546            # 10 pix between map and legend frame, 5 pix inside legend frame
547            # 25 pix from the legend frame bottom line
548            # Width: 15 pix from DC border, 5 pix inside frame, 10, 5 as above
549            # Height: 20
550    
551    class PrinterRenderer(ExportRenderer):
552    
553        # Printing as well as Export / Screen display only the visible layer.
554        honor_visibility = 1
555    

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26