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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 990 by frank, Thu May 22 16:51:24 2003 UTC revision 1837 by frank, Tue Oct 21 09:29:52 2003 UTC
# Line 8  Line 8 
8    
9  __version__ = "$Revision$"  __version__ = "$Revision$"
10    
11    from  math import fabs, cos, pi
12    
13  from Thuban import _  from Thuban import _
14    
15  import resource  import resource
# Line 17  from wxPython.wx import * Line 19  from wxPython.wx import *
19  from Thuban.Model.layer import BaseLayer  from Thuban.Model.layer import BaseLayer
20  from Thuban.Model.map import Map  from Thuban.Model.map import Map
21  from Thuban.Model.classification import ClassGroup  from Thuban.Model.classification import ClassGroup
22    from Thuban.Model.proj import PROJ_UNITS_DEGREES
23    
24  from Thuban.Model.messages import \  from Thuban.Model.messages import \
25      MAP_STACKING_CHANGED, MAP_LAYERS_ADDED, MAP_LAYERS_REMOVED, LAYER_CHANGED,\      MAP_STACKING_CHANGED, MAP_LAYERS_ADDED, MAP_LAYERS_REMOVED, LAYER_CHANGED,\
# Line 39  ID_LEGEND_PROPS = 4006 Line 42  ID_LEGEND_PROPS = 4006
42  ID_LEGEND_SHOWLAYER = 4007  ID_LEGEND_SHOWLAYER = 4007
43  ID_LEGEND_HIDELAYER = 4008  ID_LEGEND_HIDELAYER = 4008
44    
45  BMP_SIZE_W = 30  ID_POPUP_TOP = 4501
46    ID_POPUP_UP  = 4502
47    ID_POPUP_DOWN = 4503
48    ID_POPUP_BOTTOM = 4504
49    ID_POPUP_PROPS  = 4506
50    ID_POPUP_VISIBLE = 4507
51    ID_POPUP_PROJ = 4509
52    
53    BMP_SIZE_W = 15
54  BMP_SIZE_H = 15  BMP_SIZE_H = 15
55    
56  TOP_BMP = "top_layer"  TOP_BMP = "top_layer"
# Line 105  class LegendPanel(DockPanel): Line 116  class LegendPanel(DockPanel):
116          EVT_TOOL(self, ID_LEGEND_SHOWLAYER, self._OnShowLayer)          EVT_TOOL(self, ID_LEGEND_SHOWLAYER, self._OnShowLayer)
117          EVT_TOOL(self, ID_LEGEND_HIDELAYER, self._OnHideLayer)          EVT_TOOL(self, ID_LEGEND_HIDELAYER, self._OnHideLayer)
118    
119            EVT_MENU(self, ID_POPUP_PROPS, self._OnProperties)
120            EVT_MENU(self, ID_POPUP_TOP, self._OnMoveTop)
121            EVT_MENU(self, ID_POPUP_UP, self._OnMoveUp)
122            EVT_MENU(self, ID_POPUP_DOWN, self._OnMoveDown)
123            EVT_MENU(self, ID_POPUP_BOTTOM, self._OnMoveBottom)
124            EVT_MENU(self, ID_POPUP_VISIBLE, self._OnToggleVisibility)
125            EVT_MENU(self, ID_POPUP_PROJ, self._OnProjection)
126            
127          self.tree = LegendTree(self, ID_LEGEND_TREE, map, mainWindow)          self.tree = LegendTree(self, ID_LEGEND_TREE, map, mainWindow)
128    
129          panelBox.Add(self.tree, 1, wxGROW, 0)          panelBox.Add(self.tree, 1, wxGROW, 0)
# Line 179  class LegendPanel(DockPanel): Line 198  class LegendPanel(DockPanel):
198          self.tree.DoOnHideLayer()          self.tree.DoOnHideLayer()
199          pass          pass
200    
201        def _OnToggleVisibility(self, event):
202            self.tree.ToggleVisibility()
203    
204        def _OnProjection(self, event):
205            self.tree.LayerProjection()
206    
207      def __EnableButtons(self, on):      def __EnableButtons(self, on):
208          self.toolBar.EnableTool(ID_LEGEND_TOP, on)          self.toolBar.EnableTool(ID_LEGEND_TOP, on)
209          self.toolBar.EnableTool(ID_LEGEND_RAISE, on)          self.toolBar.EnableTool(ID_LEGEND_RAISE, on)
# Line 201  class LegendTree(wxTreeCtrl): Line 226  class LegendTree(wxTreeCtrl):
226          self.mainWindow = mainWindow          self.mainWindow = mainWindow
227          self.map = None          self.map = None
228          self.parent = parent          self.parent = parent
229          self.layer2id = {}          self.changing_selection = 0
230    
231            #
232            # The image list used by the wxTreeCtrl causes problems when
233            # we remove layers and/or change a classification because it
234            # changes the image indices if you remove images from the list.
235            # Rather than removing unused images we use this list to keep
236            # track of which indices are available in the image list
237            # (because of a previous removal) and then  replace those indices
238            # with new images rather than appending to the end of the image
239            # list (assuming there are any that are available).
240            #
241            self.availImgListIndices = []
242    
243          self.image_list = None          self.image_list = None
244          self.emptyImageIndex = 0          self.emptyImageIndex = 0
245    
246          self.previewer = ClassDataPreviewer()          self.previewer = ClassDataPreviewer()
247    
248            self.preventExpandCollapse = False
249            self.raiseProperties = False
250    
251          EVT_TREE_ITEM_ACTIVATED(self, ID_LEGEND_TREE, self._OnItemActivated)          EVT_TREE_ITEM_ACTIVATED(self, ID_LEGEND_TREE, self._OnItemActivated)
252          EVT_TREE_SEL_CHANGED(self, ID_LEGEND_TREE, self._OnSelChanged)          EVT_TREE_SEL_CHANGED(self, ID_LEGEND_TREE, self._OnSelChanged)
253            EVT_TREE_ITEM_EXPANDING(self, ID_LEGEND_TREE, self.OnItemExpandCollapse)
254            EVT_TREE_ITEM_COLLAPSING(self, ID_LEGEND_TREE, self.OnItemExpandCollapse)
255            EVT_TREE_ITEM_RIGHT_CLICK(self, ID_LEGEND_TREE, self._OnRightClick)
256    
257          EVT_CLOSE(self, self._OnClose)          EVT_CLOSE(self, self._OnClose)
258    
259          self.SetMap(map)          self.SetMap(map)
260    
261        def find_layer(self, layer):
262            """Return the tree item for the layer"""
263            root = self.GetRootItem()
264            id, cookie = self.GetFirstChild(root, 0)
265            while id.IsOk():
266                if self.GetPyData(id) is layer:
267                    return id
268                id, cookie = self.GetNextChild(root, cookie)
269            return None
270    
271      def _OnClose(self, event):      def _OnClose(self, event):
272          self.SetMap(None)          self.SetMap(None)
273    
# Line 224  class LegendTree(wxTreeCtrl): Line 277  class LegendTree(wxTreeCtrl):
277      def SetMap(self, map):      def SetMap(self, map):
278    
279          sub_list = [(MAP_STACKING_CHANGED, self._OnMsgMapStackingChanged),          sub_list = [(MAP_STACKING_CHANGED, self._OnMsgMapStackingChanged),
280                      (MAP_LAYERS_ADDED, self._OnMsgMapLayersAddedRemoved),                      (MAP_LAYERS_ADDED, self._OnMsgMapLayersAdded),
281                      (MAP_LAYERS_REMOVED, self._OnMsgMapLayersAddedRemoved)]                      (MAP_LAYERS_REMOVED, self._OnMsgMapLayersRemoved)]
282    
283          if self.map is not None:          if self.map is not None:
284              for msg, func in sub_list: self.map.Unsubscribe(msg, func)              for msg, func in sub_list: self.map.Unsubscribe(msg, func)
# Line 236  class LegendTree(wxTreeCtrl): Line 289  class LegendTree(wxTreeCtrl):
289                      #self._OnMsgMapsChanged)                      #self._OnMsgMapsChanged)
290              #except ConnectorError:              #except ConnectorError:
291                  #pass                  #pass
292              self.__DeleteAllItems()              self.DeleteAllItems()
293                    
294          self.map = map          self.map = map
295    
# Line 252  class LegendTree(wxTreeCtrl): Line 305  class LegendTree(wxTreeCtrl):
305          layer, group = self.GetSelectedHierarchy()          layer, group = self.GetSelectedHierarchy()
306    
307          if layer is not None:          if layer is not None:
308              self.map.TopLayer(layer)              self.map.MoveLayerToTop(layer)
309          else:          else:
310              assert False, "Shouldn't be allowed."              assert False, "Shouldn't be allowed."
311              pass              pass
# Line 279  class LegendTree(wxTreeCtrl): Line 332  class LegendTree(wxTreeCtrl):
332          layer, group = self.GetSelectedHierarchy()          layer, group = self.GetSelectedHierarchy()
333    
334          if layer is not None:          if layer is not None:
335              self.map.BottomLayer(layer)              self.map.MoveLayerToBottom(layer)
336          else:          else:
337              assert False, "Shouldn't be allowed."              assert False, "Shouldn't be allowed."
338              pass              pass
# Line 296  class LegendTree(wxTreeCtrl): Line 349  class LegendTree(wxTreeCtrl):
349              return wxTreeCtrl.OnCompareItems(self, item1, item2)              return wxTreeCtrl.OnCompareItems(self, item1, item2)
350    
351      def DoOnShowLayer(self):      def DoOnShowLayer(self):
         #self.__ShowHideLayer(True)  
352          layer, group = self.GetSelectedHierarchy()          layer, group = self.GetSelectedHierarchy()
353          layer.SetVisible(True)          layer.SetVisible(True)
354    
355      def DoOnHideLayer(self):      def DoOnHideLayer(self):
         #self.__ShowHideLayer(False)  
356          layer, group = self.GetSelectedHierarchy()          layer, group = self.GetSelectedHierarchy()
357          layer.SetVisible(False)          layer.SetVisible(False)
358    
359        def ToggleVisibility(self):
360            layer, group = self.GetSelectedHierarchy()
361    
362            layer.SetVisible(not layer.Visible())
363    
364        def LayerProjection(self):
365            self.parent.mainWindow.LayerProjection()
366    
367      def Sort(self):      def Sort(self):
368          self.SortChildren(self.GetRootItem())          self.SortChildren(self.GetRootItem())
369    
# Line 330  class LegendTree(wxTreeCtrl): Line 389  class LegendTree(wxTreeCtrl):
389          self.SetMap(self.mainWindow.Map())          self.SetMap(self.mainWindow.Map())
390                    
391      def _OnSelChanged(self, event):      def _OnSelChanged(self, event):
392            # If we change the selection from normalize_selection do nothing.
393            if self.changing_selection:
394                return
395    
396            self.normalize_selection()
397          self.__UpdateSelection()          self.__UpdateSelection()
398    
399        def normalize_selection(self):
400            """Select the layer containing currently selected item"""
401            # This is really a workaround for a bug in wx where deleting a
402            # subtree with DeleteChildren does not update the selection
403            # properly and can lead to segfaults later because the return
404            # value of GetSelection points to invalid data.
405            item = self.GetSelection()
406            while item.IsOk():
407                object = self.GetPyData(item)
408                if isinstance(object, BaseLayer):
409                    break
410                item = self.GetItemParent(item)
411            else:
412                # No layer was found in the chain of parents, so there's
413                # nothing we can do.
414                return
415    
416            self.changing_selection = 1
417            try:
418                self.SelectItem(item)
419            finally:
420                self.changing_selection = 0
421    
422    
423        def OnItemExpandCollapse(self, event):
424            if self.preventExpandCollapse:
425                event.Veto()
426                self.preventExpandCollapse = False
427    
428        def _OnRightClick(self, event):
429            """Select item and pop up a context menu"""
430    
431            # The pop up menu is related to the legend tree, so we have direct
432            # access on the tree items. The events issued by the menu are handled
433            # by the legend panel, since most of the handlers are already
434            # implemented there.
435    
436            # Update item selection to the right click
437            item = event.GetItem()
438            self.SelectItem(item)
439    
440            # Create the menu
441            menu = wxMenu("", 0)
442    
443            # The "Visible" item is a special ...
444            menuitem = wxMenuItem(menu, ID_POPUP_VISIBLE, _("Visible"),
445                                    "", wxITEM_CHECK)
446            menu.AppendItem(menuitem)
447            layer, group = self.GetSelectedHierarchy()
448            menuitem.Check(layer.Visible())
449    
450            menu.AppendSeparator()
451            menu.Append(ID_POPUP_PROPS, _("Properties"))
452            menu.Append(ID_POPUP_PROJ, _("Projection"))
453            menu.AppendSeparator()
454            menu.Append(ID_POPUP_TOP, _("Top"))
455            menu.Append(ID_POPUP_UP, _("Up"))
456            menu.Append(ID_POPUP_DOWN, _("Down"))
457            menu.Append(ID_POPUP_BOTTOM, _("Bottom"))
458    
459            # Display the menu
460            pos = event.GetPoint()
461            shift = self.ClientToScreen((0,0))
462            self.PopupMenu(menu, pos)
463    
464      def _OnItemActivated(self, event):      def _OnItemActivated(self, event):
465          self.parent.DoOnProperties()          # The following looks strange but is need under Windows to
466            # raise the Properties on double-click: The tree control
467            # always gets an Expanded / Collapsed event after the ItemActivated
468            # on double click, which raises the main window again. We add a second
469            # ItemActivated event to the queue, which simply raises the already
470            # displayed window.
471            if self.raiseProperties:
472                self.parent.DoOnProperties()
473                self.raiseProperties = False
474            else:
475                self.raiseProperties = True
476                self.preventExpandCollapse = True
477                self.parent.DoOnProperties()
478                self.AddPendingEvent(event)
479    
480      def _OnMsgLayerChanged(self, layer):      def _OnMsgLayerChanged(self, layer):
481          assert isinstance(layer, BaseLayer)          assert isinstance(layer, BaseLayer)
482    
483          id = self.layer2id[layer]          id = self.find_layer(layer)
484          assert id.IsOk()          assert id is not None
485    
486          # XXX: yikes! this is so bad, we should be doing what is          self.__FillTreeLayer(id)
         #      commented out, but there is a problem with keeping  
         #      track of the images in the image list when we replace  
         #      a layer. it ends up causing a seg fault.  
         self.__FillTree(self.map)  
487          self.__UpdateSelection()          self.__UpdateSelection()
         #self.__FillTreeLayer(id)  
488    
489      def _OnMsgMapStackingChanged(self, *args):      def _OnMsgMapStackingChanged(self, *args):
490          self.Sort()          self.Sort()
# Line 357  class LegendTree(wxTreeCtrl): Line 494  class LegendTree(wxTreeCtrl):
494              self.EnsureVisible(id)              self.EnsureVisible(id)
495          self.__UpdateSelection()          self.__UpdateSelection()
496    
497      def _OnMsgMapLayersAddedRemoved(self, map):      def _OnMsgMapLayersAdded(self, map):
498            assert map is self.map
499    
500            # Build a dict with all layers known by the the tree as keys
501            layers = {}
502            root = self.GetRootItem()
503            id, cookie = self.GetFirstChild(root, 0)
504            while id.IsOk():
505                layers[self.GetPyData(id)] = 1
506                id, cookie = self.GetNextChild(root, cookie)
507    
508            # Add layers in the map but not in the dict
509            i = 0
510            for l in map.Layers():
511                if not l in layers:
512                    self.__AddLayer(i, l)
513    
514            self.__UpdateSelection()
515    
516        def _OnMsgMapLayersRemoved(self, map):
517          assert map is self.map          assert map is self.map
518    
519          self.__FillTree(self.map)          layers = map.Layers()
520    
521            root = self.GetRootItem()
522            id, cookie = self.GetFirstChild(root, 0)
523            while id.IsOk():
524                if self.GetPyData(id) not in layers:
525                    self.__RemoveLayer(id)
526                id, cookie = self.GetNextChild(root, cookie)
527    
528    
529          self.__UpdateSelection()          self.__UpdateSelection()
530    
531      def _OnMsgLayerVisibilityChanged(self, layer):      def _OnMsgLayerVisibilityChanged(self, layer):
# Line 371  class LegendTree(wxTreeCtrl): Line 536  class LegendTree(wxTreeCtrl):
536    
537      def _OnMsgLayerTitleChanged(self, layer):      def _OnMsgLayerTitleChanged(self, layer):
538    
539          id = self.layer2id[layer]          id = self.find_layer(layer)
540          if id.IsOk():          if id.IsOk():
541              self.SetItemText(id, layer.Title())              self.SetItemText(id, layer.Title())
542          self.__UpdateSelection()          self.__UpdateSelection()
# Line 384  class LegendTree(wxTreeCtrl): Line 549  class LegendTree(wxTreeCtrl):
549    
550          self.Freeze()          self.Freeze()
551    
552          self.__DeleteAllItems()          self.DeleteAllItems()
553    
554          if map.HasLayers():          if map.HasLayers():
555                root = self.GetRootItem()
             self.image_list = wxImageList(BMP_SIZE_W, BMP_SIZE_H, False, 0)  
                                                                                   
             bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)  
             dc = wxMemoryDC()  
             dc.SelectObject(bmp)  
             dc.SetBrush(wxBLACK_BRUSH)  
             dc.Clear()  
             dc.SelectObject(wxNullBitmap)  
                                                                                   
             self.emptyImageIndex = \  
                 self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))  
                                                                                   
             self.AssignImageList(self.image_list)  
   
             root = self.AddRoot("")  
   
556              for l in map.Layers():              for l in map.Layers():
557                  id = self.PrependItem(root, l.Title())                  self.__AddLayer(0, l)
                 l.Subscribe(LAYER_CHANGED, self._OnMsgLayerChanged)  
                 l.Subscribe(LAYER_VISIBILITY_CHANGED,  
                             self._OnMsgLayerVisibilityChanged)  
                 l.Subscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)  
                 self.SetPyData(id, l)  
                 self.__SetVisibilityStyle(l.Visible(), id)  
   
                 self.layer2id[l] = id  
   
                 self.__FillTreeLayer(id)  
                 self.Expand(id)  
558    
559          self.Thaw()          self.Thaw()
560    
# Line 443  class LegendTree(wxTreeCtrl): Line 581  class LegendTree(wxTreeCtrl):
581                      bmp = self.__BuildGroupImage(g, shapeType)                      bmp = self.__BuildGroupImage(g, shapeType)
582    
583                      if bmp is None:                      if bmp is None:
584                          self.SetItemImage(id, self.emptyImageIndex)                          self.SetItemImage(id, -1)
585                            self.SetItemSelectedImage(id, -1)
586                      else:                      else:
587                          i = self.image_list.Add(bmp)                          if self.availImgListIndices:
588                                i = self.availImgListIndices.pop(0)
589                                self.image_list.Replace(i, bmp)
590                            else:
591                                i = self.image_list.Add(bmp)
592    
593                          self.SetItemImage(id, i)                          self.SetItemImage(id, i)
594                            self.SetItemSelectedImage(id, i)
595    
596          self.Thaw()          self.Thaw()
597    
# Line 462  class LegendTree(wxTreeCtrl): Line 607  class LegendTree(wxTreeCtrl):
607    
608          return bmp          return bmp
609    
610      def __DeleteAllItems(self):      def DeleteAllItems(self):
611    
612          while len(self.layer2id) > 0:          pid = self.GetRootItem()
             layer, id = self.layer2id.popitem()  
             layer.Unsubscribe(LAYER_CHANGED,  
                               self._OnMsgLayerChanged)  
             layer.Unsubscribe(LAYER_VISIBILITY_CHANGED,  
                               self._OnMsgLayerVisibilityChanged)  
             layer.Unsubscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)  
613    
614          self.DeleteAllItems()          id, cookie = self.GetFirstChild(pid, 123)
615            while id.IsOk():
616                self.__RemoveLayer(id)
617                id, cookie = self.GetNextChild(pid, cookie)
618    
619            wxTreeCtrl.DeleteAllItems(self)
620    
621        def __AddLayer(self, before, l):
622            root = self.GetRootItem()
623            id = self.InsertItemBefore(root, before,
624                                l.Title(),
625                                self.mapImageIndex,
626                                self.mapImageIndex)
627    
628            self.SetPyData(id, l)
629            self.__SetVisibilityStyle(l.Visible(), id)
630    
631            self.__FillTreeLayer(id)
632            self.Expand(id)
633    
634            l.Subscribe(LAYER_CHANGED, self._OnMsgLayerChanged)
635            l.Subscribe(LAYER_VISIBILITY_CHANGED,
636                        self._OnMsgLayerVisibilityChanged)
637            l.Subscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
638    
639        def __RemoveLayer(self, id):
640            self.DeleteChildren(id)
641    
642            layer = self.GetPyData(id)
643            layer.Unsubscribe(LAYER_CHANGED,
644                              self._OnMsgLayerChanged)
645            layer.Unsubscribe(LAYER_VISIBILITY_CHANGED,
646                              self._OnMsgLayerVisibilityChanged)
647            layer.Unsubscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
648    
649            self.Delete(id)
650    
651        def DeleteChildren(self, pid):
652            id, cookie = self.GetFirstChild(pid, 123)
653            while id.IsOk():
654                self.availImgListIndices.append(self.GetItemImage(id))
655                id, cookie = self.GetNextChild(pid, cookie)
656            wxTreeCtrl.DeleteChildren(self, pid)
657    
658        def GetRootItem(self):
659            root = wxTreeCtrl.GetRootItem(self)
660    
661            if not root.IsOk():
662                self.image_list = wxImageList(BMP_SIZE_W, BMP_SIZE_H, False, 0)
663    
664                bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)
665                dc = wxMemoryDC()
666                dc.SelectObject(bmp)
667                dc.SetBrush(wxBLACK_BRUSH)
668                dc.Clear()
669                dc.SelectObject(wxNullBitmap)
670    
671                self.emptyImageIndex = \
672                    self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))
673    
674                bmp = resource.GetBitmapResource("legend_icon_layer",
675                                                  wxBITMAP_TYPE_XPM)
676                self.mapImageIndex = \
677                    self.image_list.Add(bmp)
678    
679                self.AssignImageList(self.image_list)
680                self.availImgListIndices = []
681    
682                root = self.AddRoot("")
683    
684            return root
685    
686      def __SetVisibilityStyle(self, visible, id):      def __SetVisibilityStyle(self, visible, id):
687          font = self.GetItemFont(id)          font = self.GetItemFont(id)
# Line 489  class LegendTree(wxTreeCtrl): Line 698  class LegendTree(wxTreeCtrl):
698          self.SetItemFont(id, font)          self.SetItemFont(id, font)
699                    
700      def __ShowHideLayer(self, layer):      def __ShowHideLayer(self, layer):
701          parent = self.layer2id[layer]          parent = self.find_layer(layer)
702          assert parent.IsOk()          assert parent.IsOk()
703    
704          visible = layer.Visible()          visible = layer.Visible()
# Line 543  class ScaleBarBitmap(wxBoxSizer): Line 752  class ScaleBarBitmap(wxBoxSizer):
752          dc.SelectObject(bmp)          dc.SelectObject(bmp)
753          dc.Clear()          dc.Clear()
754    
755          self.scalebar.DrawScaleBar(scale, dc, (0,0), dc.GetSizeTuple())          if self.canvas.map is not None \
756                and self.canvas.map.projection is not None:
757    
758                # if we are using a projection with geographics coordinates
759                # we need to change the scale value based on where we are
760                # on the globe.
761                if self.canvas.map.projection.GetProjectedUnits() \
762                    == PROJ_UNITS_DEGREES:
763    
764                    width, height = self.canvas.GetSizeTuple()
765                    long, lat = self.canvas.win_to_proj(width/2, height/2)
766    
767                    # slightly inaccurate, but if we are looking at
768                    # the north/south pole we could end up dividing by zero
769                    #
770                    # it shouldn't matter for our purposes that we ignore
771                    # the original sign of lat.
772                    if fabs(lat) > 89.9: lat = 89.9
773    
774                    #
775                    # one degree is about 111,133m at the equator
776                    # we need to adjust that for latitude as
777                    # we move north/south. use the center of the map
778                    # as the point to scale the length to.
779                    #
780                    scale = scale / (111133.0 * fabs(cos(lat * pi/180)))
781    
782                self.scalebar.DrawScaleBar(scale, dc, (0,0), dc.GetSizeTuple())
783    
784          self.scalebarBitmap.SetBitmap(bmp)          self.scalebarBitmap.SetBitmap(bmp)
785    

Legend:
Removed from v.990  
changed lines
  Added in v.1837

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26