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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1750 - (show annotations)
Wed Sep 24 15:46:27 2003 UTC (21 years, 5 months ago) by bh
Original Path: trunk/thuban/Thuban/UI/renderer.py
File MIME type: text/x-python
File size: 11108 byte(s)
(ExportRenderer.render_legend): Do not
modify the list returned by map.Layers() in place since it is the
actual list of layers used by the map.

1 # Copyright (c) 2001, 2002, 2003 by Intevation GmbH
2 # Authors:
3 # Bernhard Herzog <[email protected]>
4 # Jonathan Coles <[email protected]>
5 # Frank Koormann <[email protected]>
6 #
7 # This program is free software under the GPL (>=v2)
8 # Read the file COPYING coming with Thuban for details.
9
10 __version__ = "$Revision$"
11
12 import cStringIO
13
14 from Thuban import _
15
16 from wxPython.wx import wxPoint, wxRect, wxPen, wxBrush, wxFont, \
17 wxTRANSPARENT_PEN, wxTRANSPARENT_BRUSH, \
18 wxBLACK_PEN, wxBLACK, wxSOLID, wxCROSS_HATCH, wxSWISS, wxNORMAL, \
19 wxBitmapFromImage, wxImageFromStream, wxBITMAP_TYPE_BMP
20
21 from wxproj import draw_polygon_shape, draw_polygon_init
22
23 from Thuban.UI.common import Color2wxColour
24 from Thuban.UI.classifier import ClassDataPreviewer
25 from Thuban.UI.scalebar import ScaleBar
26
27 from Thuban.Model.data import SHAPETYPE_POLYGON, SHAPETYPE_ARC, \
28 SHAPETYPE_POINT, RAW_SHAPEFILE
29
30 from Thuban.Model.color import Transparent
31 import Thuban.Model.resource
32
33 from baserenderer import BaseRenderer
34
35 class MapRenderer(BaseRenderer):
36
37 """Class to render a map onto a wxDC"""
38
39 TRANSPARENT_PEN = wxTRANSPARENT_PEN
40 TRANSPARENT_BRUSH = wxTRANSPARENT_BRUSH
41
42 make_point = wxPoint
43
44 def tools_for_property(self, prop):
45 fill = prop.GetFill()
46 if fill is Transparent:
47 brush = self.TRANSPARENT_BRUSH
48 else:
49 brush = wxBrush(Color2wxColour(fill), wxSOLID)
50
51 stroke = prop.GetLineColor()
52 if stroke is Transparent:
53 pen = self.TRANSPARENT_PEN
54 else:
55 pen = wxPen(Color2wxColour(stroke), prop.GetLineWidth(), wxSOLID)
56 return pen, brush
57
58 def low_level_renderer(self, layer):
59 """Override inherited method to provide more efficient renderers
60
61 If the underlying data format is not a shapefile or the layer
62 contains points shapes, simply use what the inherited method
63 returns.
64
65 Otherwise, i.e. for arc and polygon use the more efficient
66 wxproj.draw_polygon_shape and its corresponding parameter
67 created with wxproj.draw_polygon_init.
68 """
69 if (layer.ShapeStore().RawShapeFormat() == RAW_SHAPEFILE
70 and layer.ShapeType() in (SHAPETYPE_ARC, SHAPETYPE_POLYGON)):
71 offx, offy = self.offset
72 return (True, draw_polygon_shape,
73 draw_polygon_init(layer.ShapeStore().Shapefile(),
74 self.dc, self.map.projection,
75 layer.projection,
76 self.scale, -self.scale, offx, offy))
77 else:
78 return BaseRenderer.low_level_renderer(self, layer)
79
80 def label_font(self):
81 return wxFont(self.resolution * 10, wxSWISS, wxNORMAL, wxNORMAL)
82
83 def draw_raster_data(self, data):
84 stream = cStringIO.StringIO(data)
85 image = wxImageFromStream(stream, wxBITMAP_TYPE_BMP)
86 bitmap = wxBitmapFromImage(image)
87 self.dc.DrawBitmap(bitmap, 0, 0)
88
89
90 class ScreenRenderer(MapRenderer):
91
92 # On the screen we want to see only visible layers by default
93 honor_visibility = 1
94
95 def RenderMap(self, map, region, selected_layer, selected_shapes):
96 """Render the map.
97
98 Only the given region (a tuple in window coordinates as returned
99 by a wxrect's asTuple method) needs to be redrawn. Highlight the
100 shapes given by the ids in selected_shapes in the
101 selected_layer.
102 """
103 self.update_region = region
104 self.selected_layer = selected_layer
105 self.selected_shapes = selected_shapes
106 self.render_map(map)
107
108 def draw_shape_layer(self, layer):
109 MapRenderer.draw_shape_layer(self, layer)
110 if layer is self.selected_layer and self.selected_shapes:
111 pen = wxPen(wxBLACK, 3, wxSOLID)
112 brush = wxBrush(wxBLACK, wxCROSS_HATCH)
113
114 shapetype = layer.ShapeType()
115 useraw, func, param = self.low_level_renderer(layer)
116 args = (pen, brush)
117 for index in self.selected_shapes:
118 shape = layer.Shape(index)
119 if useraw:
120 data = shape.RawData()
121 else:
122 data = shape.Points()
123 func(param, data, *args)
124
125 def layer_shapes(self, layer):
126 """Return the shapeids covered by the region that has to be redrawn
127
128 Call the layer's ShapesInRegion method to determine the ids so
129 that it can use the quadtree.
130 """
131 # FIXME: the quad-tree should be built from the projected
132 # coordinates not the lat-long ones because it's not trivial to
133 # determine an appropriate rectangle in lat-long for a given
134 # rectangle in projected coordinates which we have to start from
135 # here.
136 proj = self.map.projection
137 if proj is not None:
138 inverse = proj.Inverse
139 else:
140 inverse = None
141
142 scale = self.scale
143 offx, offy = self.offset
144 xs = []
145 ys = []
146 x, y, width, height = self.update_region
147 for winx, winy in ((x, y), (x + width, y),
148 (x + width, y + height), (x, y + height)):
149 px = (winx - offx) / scale
150 py = -(winy - offy) / scale
151 if inverse:
152 px, py = inverse(px, py)
153 xs.append(px)
154 ys.append(py)
155 left = min(xs)
156 right = max(xs)
157 top = max(ys)
158 bottom = min(ys)
159
160 return layer.ShapesInRegion((left, bottom, right, top))
161
162
163 class ExportRenderer(ScreenRenderer):
164
165 honor_visibility = 1
166
167 def RenderMap(self, map, region, mapregion,
168 selected_layer, selected_shapes ):
169 """Render the map.
170
171 The rendering device has been specified during initialisation.
172 The device border distance was set in Thuban.UI.view.OutputTranform().
173
174 RenderMap renders a frame set (one page frame, one around
175 legend/scalebar and one around the map), the map, the legend and the
176 scalebar on the given DC. The map is rendered with the region displayed
177 in the canvas view, centered on the area available for map display.
178 """
179
180 self.update_region = region
181 self.selected_layer = selected_layer
182 self.selected_shapes = selected_shapes
183
184 # Get some dimensions
185 llx, lly, urx, ury = region
186 self.mapregion = mapregion
187 mminx, mminy, mmaxx, mmaxy = self.mapregion
188
189 # Manipulate the offset to position the map
190 offx, offy = self.offset
191 # 1. Shift to corner of map drawing area
192 offx = offx + mminx
193 offy = offy + mminy
194
195 # 2. Center the map on the map drawing area:
196 # region identifies the region on the canvas view:
197 # center of map drawing area - half the size of region: rendering origin
198 self.shiftx = (mmaxx - mminx)*0.5 - (urx - llx)*0.5
199 self.shifty = (mmaxy - mminy)*0.5 - (ury - lly)*0.5
200
201 self.offset = (offx+self.shiftx, offy+self.shifty)
202
203 # Draw the map
204 self.dc.BeginDrawing()
205 self.dc.DestroyClippingRegion()
206 self.dc.SetClippingRegion(mminx+self.shiftx, mminy+self.shifty,
207 urx, ury)
208 self.render_map(map)
209 self.dc.EndDrawing()
210
211 # Draw the rest (frames, legend, scalebar)
212 self.dc.BeginDrawing()
213 self.dc.DestroyClippingRegion()
214
215 # Force the font for Legend drawing
216 font = wxFont(self.resolution * 10, wxSWISS, wxNORMAL, wxNORMAL)
217 self.dc.SetFont(font)
218
219 self.render_frame(region)
220 self.render_legend(map)
221 self.render_scalebar(map)
222 self.dc.EndDrawing()
223
224 def render_frame(self, region):
225 """Render the frames for map and legend/scalebar."""
226
227 dc = self.dc
228 dc.SetPen(wxBLACK_PEN)
229 dc.SetBrush(wxTRANSPARENT_BRUSH)
230
231 # Dimension stuff
232 width, height = dc.GetSizeTuple()
233 mminx, mminy, mmaxx, mmaxy = self.mapregion
234
235 # Page Frame
236 dc.DrawRectangle(15,15,width-30, (mmaxy-mminy)+10)
237
238 # Map Frame
239 llx, lly, urx, ury = region
240 dc.DrawRectangle(mminx + self.shiftx, mminy + self.shifty, urx, ury)
241
242 # Legend Frame
243 dc.DrawRectangle(mmaxx+10,mminy,(width-20) - (mmaxx+10), mmaxy-mminy)
244
245 dc.DestroyClippingRegion()
246 dc.SetClippingRegion(mmaxx+10,mminy,
247 (width-20) - (mmaxx+10), mmaxy-mminy)
248
249 def render_legend(self, map):
250 """Render the legend on the Map."""
251
252 previewer = ClassDataPreviewer()
253 dc = self.dc
254 dc.SetPen(wxBLACK_PEN)
255 dc.SetBrush(wxTRANSPARENT_BRUSH)
256
257 # Dimension stuff
258 width, height = dc.GetSizeTuple()
259 mminx, mminy, mmaxx, mmaxy = self.mapregion
260 textwidth, textheight = dc.GetTextExtent("0")
261 iconwidth = textheight
262 iconheight = textheight
263 stepy = textheight+3
264 dx = 10
265 posx = mmaxx + 10 + 5 # 10 pix distance mapframe/legend frame,
266 # 5 pix inside legend frame
267 posy = mminy + 5 # 5 pix inside legend frame
268
269 # Render the legend
270 dc.SetTextForeground(wxBLACK)
271 if map.HasLayers():
272 layers = map.Layers()[:]
273 layers.reverse()
274 for l in layers:
275 if l.Visible():
276 # Render title
277 dc.DrawText(l.Title(), posx, posy)
278 posy+=stepy
279 if l.HasClassification():
280 # Render classification
281 clazz = l.GetClassification()
282 shapeType = l.ShapeType()
283 for g in clazz:
284 if g.IsVisible():
285 previewer.Draw(dc,
286 wxRect(posx+dx, posy,
287 iconwidth, iconheight),
288 g.GetProperties(), shapeType)
289 dc.DrawText(g.GetDisplayText(),
290 posx+2*dx+iconwidth, posy)
291 posy+=stepy
292
293 def render_scalebar(self, map):
294 """Render the scalebar."""
295
296 scalebar = ScaleBar(map)
297
298 # Dimension stuff
299 width, height = self.dc.GetSizeTuple()
300 mminx, mminy, mmaxx, mmaxy = self.mapregion
301
302 # Render the scalebar
303 scalebar.DrawScaleBar(self.scale, self.dc,
304 (mmaxx+10+5, mmaxy-25),
305 ((width-15-5) - (mmaxx+10+5),20)
306 )
307 # 10 pix between map and legend frame, 5 pix inside legend frame
308 # 25 pix from the legend frame bottom line
309 # Width: 15 pix from DC border, 5 pix inside frame, 10, 5 as above
310 # Height: 20
311
312 class PrinterRenderer(ExportRenderer):
313
314 # Printing as well as Export / Screen display only the visible layer.
315 honor_visibility = 1
316

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26