/[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 1115 by bh, Fri May 30 16:30:26 2003 UTC revision 2187 by jan, Sun Apr 18 20:37:45 2004 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 28  from Thuban.UI.classifier import ClassDa Line 31  from Thuban.UI.classifier import ClassDa
31  from Thuban.UI.dock import DockPanel  from Thuban.UI.dock import DockPanel
32  from Thuban.UI.scalebar import ScaleBar  from Thuban.UI.scalebar import ScaleBar
33    
34    from Thuban.UI.menu import Menu
35    
36  from Thuban.Lib.connector import ConnectorError  from Thuban.Lib.connector import ConnectorError
37    
38  ID_LEGEND_TOP = 4001  ID_LEGEND_TOP = 4001
# Line 50  SHOW_BMP  = "show_layer" Line 55  SHOW_BMP  = "show_layer"
55  HIDE_BMP  = "hide_layer"  HIDE_BMP  = "hide_layer"
56  PROPS_BMP = "layer_properties"  PROPS_BMP = "layer_properties"
57    
   
58  class LegendPanel(DockPanel):  class LegendPanel(DockPanel):
59    
60      def __init__(self, parent, map, mainWindow):      def __init__(self, parent, map, mainWindow):
# Line 179  class LegendPanel(DockPanel): Line 183  class LegendPanel(DockPanel):
183          self.tree.DoOnHideLayer()          self.tree.DoOnHideLayer()
184          pass          pass
185    
186        def _OnToggleVisibility(self, event):
187            self.tree.ToggleVisibility()
188    
189        def _OnProjection(self, event):
190            self.tree.LayerProjection()
191    
192        def _OnRemoveLayer(self, event):
193            self.mainWindow.RemoveLayer()
194    
195        def _OnShowTable(self, event):
196            self.mainWindow.LayerShowTable()
197    
198      def __EnableButtons(self, on):      def __EnableButtons(self, on):
199          self.toolBar.EnableTool(ID_LEGEND_TOP, on)          self.toolBar.EnableTool(ID_LEGEND_TOP, on)
200          self.toolBar.EnableTool(ID_LEGEND_RAISE, on)          self.toolBar.EnableTool(ID_LEGEND_RAISE, on)
# Line 201  class LegendTree(wxTreeCtrl): Line 217  class LegendTree(wxTreeCtrl):
217          self.mainWindow = mainWindow          self.mainWindow = mainWindow
218          self.map = None          self.map = None
219          self.parent = parent          self.parent = parent
         self.layer2id = {}  
220          self.changing_selection = 0          self.changing_selection = 0
221    
222          #          #
# Line 221  class LegendTree(wxTreeCtrl): Line 236  class LegendTree(wxTreeCtrl):
236    
237          self.previewer = ClassDataPreviewer()          self.previewer = ClassDataPreviewer()
238    
239            self.preventExpandCollapse = False
240            self.raiseProperties = False
241    
242          EVT_TREE_ITEM_ACTIVATED(self, ID_LEGEND_TREE, self._OnItemActivated)          EVT_TREE_ITEM_ACTIVATED(self, ID_LEGEND_TREE, self._OnItemActivated)
243          EVT_TREE_SEL_CHANGED(self, ID_LEGEND_TREE, self._OnSelChanged)          EVT_TREE_SEL_CHANGED(self, ID_LEGEND_TREE, self._OnSelChanged)
244            EVT_TREE_ITEM_EXPANDING(self, ID_LEGEND_TREE, self.OnItemExpandCollapse)
245            EVT_TREE_ITEM_COLLAPSING(self, ID_LEGEND_TREE, self.OnItemExpandCollapse)
246            EVT_TREE_ITEM_RIGHT_CLICK(self, ID_LEGEND_TREE, self._OnRightClick)
247    
248          EVT_CLOSE(self, self._OnClose)          EVT_CLOSE(self, self._OnClose)
249    
250          self.SetMap(map)          self.SetMap(map)
251    
252        def _OnRightClick(self, event):
253            """Select item and pop up a context menu"""
254    
255            # The pop up menu is related to the legend tree, so we have direct
256            # access on the tree items. The events issued by the menu are handled
257            # by the legend panel, since most of the handlers are already
258            # implemented there.
259    
260            # Update item selection to the right click
261            item = event.GetItem()
262            self.SelectItem(item)
263    
264            # Define the menu
265            popup_menu = Menu("PopUp", "",
266                              [ "layer_visibility",
267                                None,
268                                "layer_properties",
269                                "layer_projection",
270                                "layer_remove",
271                                "layer_show_table",
272                                None,
273                                "layer_to_top",
274                                "layer_raise",
275                                "layer_lower",
276                                "layer_to_bottom"
277                                ])
278    
279            # Display the menu
280            pos = event.GetPoint()
281            shift = self.ClientToScreen((0,0))
282            self.PopupMenu(self.mainWindow.build_menu(popup_menu), pos)
283    
284        def find_layer(self, layer):
285            """Return the tree item for the layer"""
286            root = self.GetRootItem()
287            id, cookie = self.GetFirstChild(root, 0)
288            while id.IsOk():
289                if self.GetPyData(id) is layer:
290                    return id
291                id, cookie = self.GetNextChild(root, cookie)
292            return None
293    
294      def _OnClose(self, event):      def _OnClose(self, event):
295          self.SetMap(None)          self.SetMap(None)
296    
# Line 316  class LegendTree(wxTreeCtrl): Line 379  class LegendTree(wxTreeCtrl):
379          layer, group = self.GetSelectedHierarchy()          layer, group = self.GetSelectedHierarchy()
380          layer.SetVisible(False)          layer.SetVisible(False)
381    
382        def ToggleVisibility(self):
383            layer, group = self.GetSelectedHierarchy()
384    
385            layer.SetVisible(not layer.Visible())
386    
387        def LayerProjection(self):
388            self.parent.mainWindow.LayerProjection()
389    
390      def Sort(self):      def Sort(self):
391          self.SortChildren(self.GetRootItem())          self.SortChildren(self.GetRootItem())
392    
# Line 372  class LegendTree(wxTreeCtrl): Line 443  class LegendTree(wxTreeCtrl):
443              self.changing_selection = 0              self.changing_selection = 0
444    
445    
446        def OnItemExpandCollapse(self, event):
447            if self.preventExpandCollapse:
448                event.Veto()
449                self.preventExpandCollapse = False
450    
451      def _OnItemActivated(self, event):      def _OnItemActivated(self, event):
452          self.parent.DoOnProperties()          # The following looks strange but is need under Windows to
453            # raise the Properties on double-click: The tree control
454            # always gets an Expanded / Collapsed event after the ItemActivated
455            # on double click, which raises the main window again. We add a second
456            # ItemActivated event to the queue, which simply raises the already
457            # displayed window.
458            if self.raiseProperties:
459                self.parent.DoOnProperties()
460                self.raiseProperties = False
461            else:
462                self.raiseProperties = True
463                self.preventExpandCollapse = True
464                self.parent.DoOnProperties()
465                self.AddPendingEvent(event)
466    
467      def _OnMsgLayerChanged(self, layer):      def _OnMsgLayerChanged(self, layer):
468          assert isinstance(layer, BaseLayer)          assert isinstance(layer, BaseLayer)
469    
470          id = self.layer2id[layer]          id = self.find_layer(layer)
471          assert id.IsOk()          assert id is not None
472    
473          self.__FillTreeLayer(id)          self.__FillTreeLayer(id)
474          self.__UpdateSelection()          self.__UpdateSelection()
# Line 395  class LegendTree(wxTreeCtrl): Line 484  class LegendTree(wxTreeCtrl):
484      def _OnMsgMapLayersAdded(self, map):      def _OnMsgMapLayersAdded(self, map):
485          assert map is self.map          assert map is self.map
486    
487            # Build a dict with all layers known by the the tree as keys
488            layers = {}
489          root = self.GetRootItem()          root = self.GetRootItem()
490            id, cookie = self.GetFirstChild(root, 0)
491            while id.IsOk():
492                layers[self.GetPyData(id)] = 1
493                id, cookie = self.GetNextChild(root, cookie)
494    
495            # Add layers in the map but not in the dict
496          i = 0          i = 0
497          for l in map.Layers():          for l in map.Layers():
498              if not self.layer2id.has_key(l):              if not l in layers:
499                  self.__AddLayer(i, l)                  self.__AddLayer(i, l)
500    
501          self.__UpdateSelection()          self.__UpdateSelection()
# Line 407  class LegendTree(wxTreeCtrl): Line 503  class LegendTree(wxTreeCtrl):
503      def _OnMsgMapLayersRemoved(self, map):      def _OnMsgMapLayersRemoved(self, map):
504          assert map is self.map          assert map is self.map
505    
         layer, group = self.GetSelectedHierarchy()  
   
         if layer is None:  
             assert False, "Shouldn't be allowed."  
             return  
   
506          layers = map.Layers()          layers = map.Layers()
507    
508          for layer, id in self.layer2id.items():          root = self.GetRootItem()
509              if layer not in layers:          id, cookie = self.GetFirstChild(root, 0)
510                  if id.IsOk():          while id.IsOk():
511                      self.__RemoveLayer(id)              if self.GetPyData(id) not in layers:
512                    self.__RemoveLayer(id)
513                id, cookie = self.GetNextChild(root, cookie)
514    
515    
516          self.__UpdateSelection()          self.__UpdateSelection()
517    
# Line 430  class LegendTree(wxTreeCtrl): Line 523  class LegendTree(wxTreeCtrl):
523    
524      def _OnMsgLayerTitleChanged(self, layer):      def _OnMsgLayerTitleChanged(self, layer):
525    
526          id = self.layer2id[layer]          id = self.find_layer(layer)
527          if id.IsOk():          if id.IsOk():
528              self.SetItemText(id, layer.Title())              self.SetItemText(id, layer.Title())
529          self.__UpdateSelection()          self.__UpdateSelection()
# Line 522  class LegendTree(wxTreeCtrl): Line 615  class LegendTree(wxTreeCtrl):
615          self.SetPyData(id, l)          self.SetPyData(id, l)
616          self.__SetVisibilityStyle(l.Visible(), id)          self.__SetVisibilityStyle(l.Visible(), id)
617    
         self.layer2id[l] = id  
   
618          self.__FillTreeLayer(id)          self.__FillTreeLayer(id)
619          self.Expand(id)          self.Expand(id)
620    
# Line 543  class LegendTree(wxTreeCtrl): Line 634  class LegendTree(wxTreeCtrl):
634          layer.Unsubscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)          layer.Unsubscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
635    
636          self.Delete(id)          self.Delete(id)
         del self.layer2id[layer]  
637    
638      def DeleteChildren(self, pid):      def DeleteChildren(self, pid):
639          id, cookie = self.GetFirstChild(pid, 123)          id, cookie = self.GetFirstChild(pid, 123)
# Line 595  class LegendTree(wxTreeCtrl): Line 685  class LegendTree(wxTreeCtrl):
685          self.SetItemFont(id, font)          self.SetItemFont(id, font)
686                    
687      def __ShowHideLayer(self, layer):      def __ShowHideLayer(self, layer):
688          parent = self.layer2id[layer]          parent = self.find_layer(layer)
689          assert parent.IsOk()          assert parent.IsOk()
690    
691          visible = layer.Visible()          visible = layer.Visible()
# Line 649  class ScaleBarBitmap(wxBoxSizer): Line 739  class ScaleBarBitmap(wxBoxSizer):
739          dc.SelectObject(bmp)          dc.SelectObject(bmp)
740          dc.Clear()          dc.Clear()
741    
742          self.scalebar.DrawScaleBar(scale, dc, (0,0), dc.GetSizeTuple())          if self.canvas.map is not None \
743                and self.canvas.map.projection is not None:
744    
745                # if we are using a projection with geographics coordinates
746                # we need to change the scale value based on where we are
747                # on the globe.
748                if self.canvas.map.projection.GetProjectedUnits() \
749                    == PROJ_UNITS_DEGREES:
750    
751                    width, height = self.canvas.GetSizeTuple()
752                    long, lat = self.canvas.win_to_proj(width/2, height/2)
753    
754                    # slightly inaccurate, but if we are looking at
755                    # the north/south pole we could end up dividing by zero
756                    #
757                    # it shouldn't matter for our purposes that we ignore
758                    # the original sign of lat.
759                    if fabs(lat) > 89.9: lat = 89.9
760    
761                    #
762                    # one degree is about 111,133m at the equator
763                    # we need to adjust that for latitude as
764                    # we move north/south. use the center of the map
765                    # as the point to scale the length to.
766                    #
767                    scale = scale / (111133.0 * fabs(cos(lat * pi/180)))
768    
769                self.scalebar.DrawScaleBar(scale, dc, (0,0), dc.GetSizeTuple())
770    
771          self.scalebarBitmap.SetBitmap(bmp)          self.scalebarBitmap.SetBitmap(bmp)
772    

Legend:
Removed from v.1115  
changed lines
  Added in v.2187

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26