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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1252 - (show annotations)
Fri Jun 20 09:28:08 2003 UTC (21 years, 8 months ago) by jonathan
Original Path: trunk/thuban/Thuban/UI/legend.py
File MIME type: text/x-python
File size: 22320 byte(s)
(ScaleBarBitmap.__SetScale): Do scale
        adjustment here if the map projection uses degrees.

1 # Copyright (c) 2001, 2002, 2003 by Intevation GmbH
2 # Authors:
3 # Jonathan Coles <[email protected]>
4 # Frank Koormann <[email protected]>
5 #
6 # This program is free software under the GPL (>=v2)
7 # Read the file COPYING coming with Thuban for details.
8
9 __version__ = "$Revision$"
10
11 from math import fabs, cos, pi
12
13 from Thuban import _
14
15 import resource
16
17 from wxPython.wx import *
18
19 from Thuban.Model.layer import BaseLayer
20 from Thuban.Model.map import Map
21 from Thuban.Model.classification import ClassGroup
22 from Thuban.Model.proj import PROJ_UNITS_DEGREES
23
24 from Thuban.Model.messages import \
25 MAP_STACKING_CHANGED, MAP_LAYERS_ADDED, MAP_LAYERS_REMOVED, LAYER_CHANGED,\
26 LAYER_VISIBILITY_CHANGED, TITLE_CHANGED
27
28 from Thuban.UI.messages import SCALE_CHANGED
29
30 from Thuban.UI.classifier import ClassDataPreviewer
31 from Thuban.UI.dock import DockPanel
32 from Thuban.UI.scalebar import ScaleBar
33
34 from Thuban.Lib.connector import ConnectorError
35
36 ID_LEGEND_TOP = 4001
37 ID_LEGEND_RAISE = 4002
38 ID_LEGEND_LOWER = 4003
39 ID_LEGEND_BOTTOM = 4004
40 ID_LEGEND_TREE = 4005
41 ID_LEGEND_PROPS = 4006
42 ID_LEGEND_SHOWLAYER = 4007
43 ID_LEGEND_HIDELAYER = 4008
44
45 BMP_SIZE_W = 15
46 BMP_SIZE_H = 15
47
48 TOP_BMP = "top_layer"
49 RAISE_BMP = "raise_layer"
50 LOWER_BMP = "lower_layer"
51 BOTTOM_BMP = "bottom_layer"
52 SHOW_BMP = "show_layer"
53 HIDE_BMP = "hide_layer"
54 PROPS_BMP = "layer_properties"
55
56
57 class LegendPanel(DockPanel):
58
59 def __init__(self, parent, map, mainWindow):
60 DockPanel.__init__(self, parent, -1)
61
62 self.mainWindow = mainWindow
63 self.parent = parent
64
65 self.buttons = []
66
67 panelBox = wxBoxSizer(wxVERTICAL)
68
69 self.toolBar = wxToolBar(self, -1)
70 self.toolBar.SetToolBitmapSize(wxSize(24, 24))
71
72 bmp = resource.GetBitmapResource(TOP_BMP, wxBITMAP_TYPE_XPM)
73 self.toolBar.AddTool(ID_LEGEND_TOP, bmp,
74 shortHelpString=_("Top Layer"))
75
76 bmp = resource.GetBitmapResource(RAISE_BMP, wxBITMAP_TYPE_XPM)
77 self.toolBar.AddTool(ID_LEGEND_RAISE, bmp,
78 shortHelpString=_("Raise Layer"))
79
80 bmp = resource.GetBitmapResource(LOWER_BMP, wxBITMAP_TYPE_XPM)
81 self.toolBar.AddTool(ID_LEGEND_LOWER, bmp,
82 shortHelpString=_("Lower Layer"))
83
84 bmp = resource.GetBitmapResource(BOTTOM_BMP, wxBITMAP_TYPE_XPM)
85 self.toolBar.AddTool(ID_LEGEND_BOTTOM, bmp,
86 shortHelpString=_("Bottom Layer"))
87
88 bmp = resource.GetBitmapResource(SHOW_BMP, wxBITMAP_TYPE_XPM)
89 self.toolBar.AddTool(ID_LEGEND_SHOWLAYER, bmp,
90 shortHelpString=_("Show Layer"))
91
92 bmp = resource.GetBitmapResource(HIDE_BMP, wxBITMAP_TYPE_XPM)
93 self.toolBar.AddTool(ID_LEGEND_HIDELAYER, bmp,
94 shortHelpString=_("Hide Layer"))
95
96 bmp = resource.GetBitmapResource(PROPS_BMP, wxBITMAP_TYPE_XPM)
97 self.toolBar.AddTool(ID_LEGEND_PROPS, bmp,
98 shortHelpString=_("Edit Layer Properties"))
99
100 self.toolBar.Realize()
101 panelBox.Add(self.toolBar, 0, wxGROW, 0)
102
103 EVT_TOOL(self, ID_LEGEND_TOP, self._OnMoveTop)
104 EVT_TOOL(self, ID_LEGEND_RAISE, self._OnMoveUp)
105 EVT_TOOL(self, ID_LEGEND_LOWER, self._OnMoveDown)
106 EVT_TOOL(self, ID_LEGEND_BOTTOM, self._OnMoveBottom)
107 EVT_TOOL(self, ID_LEGEND_PROPS, self._OnProperties)
108 EVT_TOOL(self, ID_LEGEND_SHOWLAYER, self._OnShowLayer)
109 EVT_TOOL(self, ID_LEGEND_HIDELAYER, self._OnHideLayer)
110
111 self.tree = LegendTree(self, ID_LEGEND_TREE, map, mainWindow)
112
113 panelBox.Add(self.tree, 1, wxGROW, 0)
114
115 self.scalebarbitmap = ScaleBarBitmap(self, map, mainWindow)
116 panelBox.Add(self.scalebarbitmap, 0, wxGROW, 0)
117
118 self.SetAutoLayout(True)
119 self.SetSizer(panelBox)
120 panelBox.SetSizeHints(self)
121
122
123 self.panelBox = panelBox
124
125 self.__EnableButtons(False)
126
127 self.Create()
128
129 EVT_CLOSE(self, self._OnClose)
130
131
132 def GetMap(self):
133 return self.tree.GetMap()
134
135 def SetMap(self, map):
136 self.tree.SetMap(map)
137 self.scalebarbitmap.SetCanvas(self.mainWindow.canvas)
138
139 def DoOnSelChanged(self, layer, group):
140
141 ok = isinstance(layer, BaseLayer)
142 self.__EnableButtons(ok)
143
144 self.mainWindow.SelectLayer(layer)
145
146 def DoOnProperties(self):
147 list = self.tree.GetSelectedHierarchy()
148
149 ok = isinstance(list[0], BaseLayer)
150 if ok:
151 self.mainWindow.OpenLayerProperties(list[0], list[1])
152
153 def Destroy(self):
154 self.__Close()
155
156 def _OnProperties(self, event):
157 self.DoOnProperties()
158
159 def _OnMoveTop(self, event):
160 self.tree.MoveCurrentItemTop()
161
162 def _OnMoveUp(self, event):
163 self.tree.MoveCurrentItemUp()
164
165 def _OnMoveDown(self, event):
166 self.tree.MoveCurrentItemDown()
167
168 def _OnMoveBottom(self, event):
169 self.tree.MoveCurrentItemBottom()
170
171 def _OnShowLayer(self, event):
172 self.tree.DoOnShowLayer()
173 pass
174
175 #def Close(self, force = False):
176 #DockPanel.Close(self, force)
177
178 def _OnClose(self, event):
179 self.__Close()
180
181 def _OnHideLayer(self, event):
182 self.tree.DoOnHideLayer()
183 pass
184
185 def __EnableButtons(self, on):
186 self.toolBar.EnableTool(ID_LEGEND_TOP, on)
187 self.toolBar.EnableTool(ID_LEGEND_RAISE, on)
188 self.toolBar.EnableTool(ID_LEGEND_LOWER, on)
189 self.toolBar.EnableTool(ID_LEGEND_BOTTOM, on)
190 self.toolBar.EnableTool(ID_LEGEND_SHOWLAYER, on)
191 self.toolBar.EnableTool(ID_LEGEND_HIDELAYER, on)
192 self.toolBar.EnableTool(ID_LEGEND_PROPS, on)
193
194 def __Close(self):
195 self.tree.Close()
196
197 class LegendTree(wxTreeCtrl):
198
199 def __init__(self, parent, id, map, mainWindow):
200 wxTreeCtrl.__init__(self, parent, id,
201 style = wxTR_DEFAULT_STYLE | wxTR_HIDE_ROOT,
202 size = (200, 200))
203
204 self.mainWindow = mainWindow
205 self.map = None
206 self.parent = parent
207 self.changing_selection = 0
208
209 #
210 # The image list used by the wxTreeCtrl causes problems when
211 # we remove layers and/or change a classification because it
212 # changes the image indices if you remove images from the list.
213 # Rather than removing unused images we use this list to keep
214 # track of which indices are available in the image list
215 # (because of a previous removal) and then replace those indices
216 # with new images rather than appending to the end of the image
217 # list (assuming there are any that are available).
218 #
219 self.availImgListIndices = []
220
221 self.image_list = None
222 self.emptyImageIndex = 0
223
224 self.previewer = ClassDataPreviewer()
225
226 self.preventExpandCollapse = False
227 self.raiseProperties = False
228
229 EVT_TREE_ITEM_ACTIVATED(self, ID_LEGEND_TREE, self._OnItemActivated)
230 EVT_TREE_SEL_CHANGED(self, ID_LEGEND_TREE, self._OnSelChanged)
231 EVT_TREE_ITEM_EXPANDING(self, ID_LEGEND_TREE, self.OnItemExpandCollapse)
232 EVT_TREE_ITEM_COLLAPSING(self, ID_LEGEND_TREE, self.OnItemExpandCollapse)
233
234 EVT_CLOSE(self, self._OnClose)
235
236 self.SetMap(map)
237
238 def find_layer(self, layer):
239 """Return the tree item for the layer"""
240 root = self.GetRootItem()
241 id, cookie = self.GetFirstChild(root, 0)
242 while id.IsOk():
243 if self.GetPyData(id) is layer:
244 return id
245 id, cookie = self.GetNextChild(root, cookie)
246 return None
247
248 def _OnClose(self, event):
249 self.SetMap(None)
250
251 def GetMap(self):
252 return self.map
253
254 def SetMap(self, map):
255
256 sub_list = [(MAP_STACKING_CHANGED, self._OnMsgMapStackingChanged),
257 (MAP_LAYERS_ADDED, self._OnMsgMapLayersAdded),
258 (MAP_LAYERS_REMOVED, self._OnMsgMapLayersRemoved)]
259
260 if self.map is not None:
261 for msg, func in sub_list: self.map.Unsubscribe(msg, func)
262 #self.mainWindow.application.Unsubscribe(SESSION_REPLACED,
263 #self._OnMsgMapsChanged)
264 #try:
265 #self.mainWindow.application.session.Unsubscribe(MAPS_CHANGED,
266 #self._OnMsgMapsChanged)
267 #except ConnectorError:
268 #pass
269 self.DeleteAllItems()
270
271 self.map = map
272
273 if self.map is not None:
274 for msg, func in sub_list: self.map.Subscribe(msg, func)
275 #self.mainWindow.application.session.Subscribe(MAPS_CHANGED,
276 #self._OnMsgMapsChanged)
277 #self.mainWindow.application.Subscribe(SESSION_REPLACED,
278 #self._OnMsgMapsChanged)
279 self.__FillTree(self.map)
280
281 def MoveCurrentItemTop(self):
282 layer, group = self.GetSelectedHierarchy()
283
284 if layer is not None:
285 self.map.MoveLayerToTop(layer)
286 else:
287 assert False, "Shouldn't be allowed."
288 pass
289
290 def MoveCurrentItemUp(self):
291 layer, group = self.GetSelectedHierarchy()
292
293 if layer is not None:
294 self.map.RaiseLayer(layer)
295 else:
296 assert False, "Shouldn't be allowed."
297 pass
298
299 def MoveCurrentItemDown(self):
300 layer, group = self.GetSelectedHierarchy()
301
302 if layer is not None:
303 self.map.LowerLayer(layer)
304 else:
305 assert False, "Shouldn't be allowed."
306 pass
307
308 def MoveCurrentItemBottom(self):
309 layer, group = self.GetSelectedHierarchy()
310
311 if layer is not None:
312 self.map.MoveLayerToBottom(layer)
313 else:
314 assert False, "Shouldn't be allowed."
315 pass
316
317 def OnCompareItems(self, item1, item2):
318
319 data1 = self.GetPyData(item1)
320 data2 = self.GetPyData(item2)
321
322 if isinstance(data1, BaseLayer):
323 layers = self.map.Layers()
324 return layers.index(data2) - layers.index(data1)
325 else:
326 return wxTreeCtrl.OnCompareItems(self, item1, item2)
327
328 def DoOnShowLayer(self):
329 layer, group = self.GetSelectedHierarchy()
330 layer.SetVisible(True)
331
332 def DoOnHideLayer(self):
333 layer, group = self.GetSelectedHierarchy()
334 layer.SetVisible(False)
335
336 def Sort(self):
337 self.SortChildren(self.GetRootItem())
338
339 def GetSelectedHierarchy(self):
340 id = self.GetSelection()
341
342 if not id.IsOk():
343 return (None, None)
344
345 layer = self.GetPyData(id)
346 group = None
347
348 if isinstance(layer, ClassGroup):
349 id = self.GetItemParent(id)
350 assert id.IsOk()
351 group = layer
352 layer = self.GetPyData(id)
353
354 return (layer, group)
355
356 def _OnMsgMapsChanged(self):
357 #print self.map is self.mainWindow.Map()
358 self.SetMap(self.mainWindow.Map())
359
360 def _OnSelChanged(self, event):
361 # If we change the selection from normalize_selection do nothing.
362 if self.changing_selection:
363 return
364
365 self.normalize_selection()
366 self.__UpdateSelection()
367
368 def normalize_selection(self):
369 """Select the layer containing currently selected item"""
370 # This is really a workaround for a bug in wx where deleting a
371 # subtree with DeleteChildren does not update the selection
372 # properly and can lead to segfaults later because the return
373 # value of GetSelection points to invalid data.
374 item = self.GetSelection()
375 while item.IsOk():
376 object = self.GetPyData(item)
377 if isinstance(object, BaseLayer):
378 break
379 item = self.GetItemParent(item)
380 else:
381 # No layer was found in the chain of parents, so there's
382 # nothing we can do.
383 return
384
385 self.changing_selection = 1
386 try:
387 self.SelectItem(item)
388 finally:
389 self.changing_selection = 0
390
391
392 def OnItemExpandCollapse(self, event):
393 if self.preventExpandCollapse:
394 event.Veto()
395 self.preventExpandCollapse = False
396
397 def _OnItemActivated(self, event):
398 # The following looks strange but is need under Windows to
399 # raise the Properties on double-click: The tree control
400 # always gets an Expanded / Collapsed event after the ItemActivated
401 # on double click, which raises the main window again. We add a second
402 # ItemActivated event to the queue, which simply raises the already
403 # displayed window.
404 if self.raiseProperties:
405 self.parent.DoOnProperties()
406 self.raiseProperties = False
407 else:
408 self.raiseProperties = True
409 self.preventExpandCollapse = True
410 self.parent.DoOnProperties()
411 self.AddPendingEvent(event)
412
413 def _OnMsgLayerChanged(self, layer):
414 assert isinstance(layer, BaseLayer)
415
416 id = self.find_layer(layer)
417 assert id is not None
418
419 self.__FillTreeLayer(id)
420 self.__UpdateSelection()
421
422 def _OnMsgMapStackingChanged(self, *args):
423 self.Sort()
424 id = self.GetSelection()
425
426 if id.IsOk():
427 self.EnsureVisible(id)
428 self.__UpdateSelection()
429
430 def _OnMsgMapLayersAdded(self, map):
431 assert map is self.map
432
433 # Build a dict with all layers known by the the tree as keys
434 layers = {}
435 root = self.GetRootItem()
436 id, cookie = self.GetFirstChild(root, 0)
437 while id.IsOk():
438 layers[self.GetPyData(id)] = 1
439 id, cookie = self.GetNextChild(root, cookie)
440
441 # Add layers in the map but not in the dict
442 i = 0
443 for l in map.Layers():
444 if not l in layers:
445 self.__AddLayer(i, l)
446
447 self.__UpdateSelection()
448
449 def _OnMsgMapLayersRemoved(self, map):
450 assert map is self.map
451
452 layers = map.Layers()
453
454 root = self.GetRootItem()
455 id, cookie = self.GetFirstChild(root, 0)
456 while id.IsOk():
457 if self.GetPyData(id) not in layers:
458 self.__RemoveLayer(id)
459 id, cookie = self.GetNextChild(root, cookie)
460
461
462 self.__UpdateSelection()
463
464 def _OnMsgLayerVisibilityChanged(self, layer):
465 assert isinstance(layer, BaseLayer)
466
467 self.__ShowHideLayer(layer)
468 self.__UpdateSelection()
469
470 def _OnMsgLayerTitleChanged(self, layer):
471
472 id = self.find_layer(layer)
473 if id.IsOk():
474 self.SetItemText(id, layer.Title())
475 self.__UpdateSelection()
476
477 def __UpdateSelection(self):
478 layer, group = self.GetSelectedHierarchy()
479 self.parent.DoOnSelChanged(layer, group)
480
481 def __FillTree(self, map):
482
483 self.Freeze()
484
485 self.DeleteAllItems()
486
487 if map.HasLayers():
488 root = self.GetRootItem()
489 for l in map.Layers():
490 self.__AddLayer(0, l)
491
492 self.Thaw()
493
494 def __FillTreeLayer(self, pid):
495 layer = self.GetPyData(pid)
496
497 self.Freeze()
498
499 self.DeleteChildren(pid)
500
501 if layer.HasClassification():
502
503 clazz = layer.GetClassification()
504
505 shapeType = layer.ShapeType()
506
507 show = layer.Visible()
508 for g in clazz:
509 if g.IsVisible():
510 id = self.AppendItem(pid, g.GetDisplayText())
511 self.SetPyData(id, g)
512 self.__SetVisibilityStyle(show, id)
513
514 bmp = self.__BuildGroupImage(g, shapeType)
515
516 if bmp is None:
517 self.SetItemImage(id, -1)
518 self.SetItemSelectedImage(id, -1)
519 else:
520 if self.availImgListIndices:
521 i = self.availImgListIndices.pop(0)
522 self.image_list.Replace(i, bmp)
523 else:
524 i = self.image_list.Add(bmp)
525
526 self.SetItemImage(id, i)
527 self.SetItemSelectedImage(id, i)
528
529 self.Thaw()
530
531 def __BuildGroupImage(self, group, shapeType):
532
533 bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)
534 #brush = wxBrush(Color2wxColour(item[1]), wxSOLID)
535 dc = wxMemoryDC()
536 dc.SelectObject(bmp)
537 dc.Clear()
538
539 self.previewer.Draw(dc, None, group.GetProperties(), shapeType)
540
541 return bmp
542
543 def DeleteAllItems(self):
544
545 pid = self.GetRootItem()
546
547 id, cookie = self.GetFirstChild(pid, 123)
548 while id.IsOk():
549 self.__RemoveLayer(id)
550 id, cookie = self.GetNextChild(pid, cookie)
551
552 wxTreeCtrl.DeleteAllItems(self)
553
554 def __AddLayer(self, before, l):
555 root = self.GetRootItem()
556 id = self.InsertItemBefore(root, before,
557 l.Title(),
558 self.mapImageIndex,
559 self.mapImageIndex)
560
561 self.SetPyData(id, l)
562 self.__SetVisibilityStyle(l.Visible(), id)
563
564 self.__FillTreeLayer(id)
565 self.Expand(id)
566
567 l.Subscribe(LAYER_CHANGED, self._OnMsgLayerChanged)
568 l.Subscribe(LAYER_VISIBILITY_CHANGED,
569 self._OnMsgLayerVisibilityChanged)
570 l.Subscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
571
572 def __RemoveLayer(self, id):
573 self.DeleteChildren(id)
574
575 layer = self.GetPyData(id)
576 layer.Unsubscribe(LAYER_CHANGED,
577 self._OnMsgLayerChanged)
578 layer.Unsubscribe(LAYER_VISIBILITY_CHANGED,
579 self._OnMsgLayerVisibilityChanged)
580 layer.Unsubscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
581
582 self.Delete(id)
583
584 def DeleteChildren(self, pid):
585 id, cookie = self.GetFirstChild(pid, 123)
586 while id.IsOk():
587 self.availImgListIndices.append(self.GetItemImage(id))
588 id, cookie = self.GetNextChild(pid, cookie)
589 wxTreeCtrl.DeleteChildren(self, pid)
590
591 def GetRootItem(self):
592 root = wxTreeCtrl.GetRootItem(self)
593
594 if not root.IsOk():
595 self.image_list = wxImageList(BMP_SIZE_W, BMP_SIZE_H, False, 0)
596
597 bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)
598 dc = wxMemoryDC()
599 dc.SelectObject(bmp)
600 dc.SetBrush(wxBLACK_BRUSH)
601 dc.Clear()
602 dc.SelectObject(wxNullBitmap)
603
604 self.emptyImageIndex = \
605 self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))
606
607 bmp = resource.GetBitmapResource("legend_icon_layer",
608 wxBITMAP_TYPE_XPM)
609 self.mapImageIndex = \
610 self.image_list.Add(bmp)
611
612 self.AssignImageList(self.image_list)
613 self.availImgListIndices = []
614
615 root = self.AddRoot("")
616
617 return root
618
619 def __SetVisibilityStyle(self, visible, id):
620 font = self.GetItemFont(id)
621
622 if visible:
623 font.SetStyle(wxNORMAL)
624 color = wxBLACK
625 else:
626 #font.SetStyle(wxITALIC)
627 font.SetStyle(wxNORMAL)
628 color = wxLIGHT_GREY
629
630 self.SetItemTextColour(id, color)
631 self.SetItemFont(id, font)
632
633 def __ShowHideLayer(self, layer):
634 parent = self.find_layer(layer)
635 assert parent.IsOk()
636
637 visible = layer.Visible()
638
639 self.__SetVisibilityStyle(visible, parent)
640
641 id, cookie = self.GetFirstChild(parent, 123)
642
643 while id.IsOk():
644 self.__SetVisibilityStyle(visible, id)
645 id, cookie = self.GetNextChild(parent, cookie)
646
647 class ScaleBarBitmap(wxBoxSizer):
648
649 def __init__(self, parent, map, mainWindow):
650 # While the width is fixed, get the height _now_.
651 dc = wxMemoryDC()
652 textwidth, textheight = dc.GetTextExtent("%d"%0)
653 self.width = 210
654 self.height = textheight + 3*2 + 8
655
656 wxBoxSizer.__init__(self, wxVERTICAL)
657 bmp=wxEmptyBitmap(self.width, self.height)
658 self.scalebarBitmap = wxStaticBitmap(parent, -1, bmp)
659 self.Add(self.scalebarBitmap, 0, wxALIGN_CENTER|wxLEFT|wxTOP|wxRIGHT, 1)
660
661 self.mainWindow = mainWindow
662 self.parent = parent
663 self.canvas = None
664 self.SetCanvas(self.mainWindow.canvas)
665
666 def SetCanvas(self, canvas):
667 sub_list = [(SCALE_CHANGED, self._OnMsgScaleChanged)]
668
669 if self.canvas is not None:
670 for msg, func in sub_list: self.canvas.Unsubscribe(msg, func)
671
672 self.canvas = canvas
673 self.scalebar = ScaleBar(canvas.map)
674
675 if self.canvas is not None:
676 for msg, func in sub_list: self.canvas.Subscribe(msg, func)
677 self.__SetScale(self.canvas.scale)
678
679 def _OnMsgScaleChanged(self, scale):
680 self.__SetScale(scale)
681
682 def __SetScale(self, scale):
683 bmp = wxEmptyBitmap(self.width, self.height)
684 dc = wxMemoryDC()
685 dc.SelectObject(bmp)
686 dc.Clear()
687
688 if self.canvas.map is not None \
689 and self.canvas.map.projection is not None:
690
691 # if we are using a projection with geographics coordinates
692 # we need to change the scale value based on where we are
693 # on the globe.
694 if self.canvas.map.projection.GetProjectedUnits() \
695 == PROJ_UNITS_DEGREES:
696
697 width, height = self.canvas.GetSizeTuple()
698 long, lat = self.canvas.win_to_proj(width/2, height/2)
699
700 # slightly inaccurate, but if we are looking at
701 # the north/south pole we could end up dividing by zero
702 #
703 # it shouldn't matter for our purposes that we ignore
704 # the original sign of lat.
705 if fabs(lat) > 89.9: lat = 89.9
706
707 #
708 # one degree is about 111,133m at the equator
709 # we need to adjust that for latitude as
710 # we move north/south. use the center of the map
711 # as the point to scale the length to.
712 #
713 scale = scale / (111133.0 * fabs(cos(lat * pi/180)))
714
715 self.scalebar.DrawScaleBar(scale, dc, (0,0), dc.GetSizeTuple())
716
717 self.scalebarBitmap.SetBitmap(bmp)
718

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26