/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/Model/map.py
ViewVC logotype

Diff of /branches/WIP-pyshapelib-bramz/Thuban/Model/map.py

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

revision 6 by bh, Tue Aug 28 15:41:52 2001 UTC revision 1099 by jonathan, Fri May 30 06:28:02 2003 UTC
# Line 1  Line 1 
1  # Copyright (c) 2001 by Intevation GmbH  # Copyright (c) 2001, 2002 by Intevation GmbH
2  # Authors:  # Authors:
3  # Bernhard Herzog <[email protected]>  # Bernhard Herzog <[email protected]>
4  #  #
# Line 7  Line 7 
7    
8  __version__ = "$Revision$"  __version__ = "$Revision$"
9    
10  from messages import LAYERS_CHANGED, MAP_PROJECTION_CHANGED, \  from messages import MAP_LAYERS_CHANGED, MAP_PROJECTION_CHANGED, \
11       CHANGED, LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \       CHANGED, LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \
12       LAYER_VISIBILITY_CHANGED       LAYER_VISIBILITY_CHANGED, LAYER_CHANGED, MAP_STACKING_CHANGED, \
13         MAP_LAYERS_ADDED, MAP_LAYERS_REMOVED
14    
15    from Thuban import _
16    
17  from base import TitledObject, Modifiable  from base import TitledObject, Modifiable
18    
19  from label import LabelLayer  from label import LabelLayer
20    
21    
   
22  class Map(TitledObject, Modifiable):  class Map(TitledObject, Modifiable):
23    
24      """Represent a map. A map is simply a list of layers.      """Represent a map. A map is simply a list of layers.
# Line 25  class Map(TitledObject, Modifiable): Line 27  class Map(TitledObject, Modifiable):
27    
28          TITLE_CHANGED -- The title has changed. Parameter: the map.          TITLE_CHANGED -- The title has changed. Parameter: the map.
29    
30          LAYERS_CHANGED -- Layers were added, removed or rearranged.          MAP_LAYERS_CHANGED -- Layers were added, removed or rearranged.
31                          Parameters: the map                          Parameters: the map
32    
33          MAP_PROJECTION_CHANGED -- the map's projection has changed.          MAP_PROJECTION_CHANGED -- the map's projection has changed.
34                          Parameter: the map                          Parameter: the map
35      """      """
36    
37      forwarded_channels = (LAYER_PROJECTION_CHANGED,      forwarded_channels = (CHANGED,
38                              LAYER_PROJECTION_CHANGED,
39                            LAYER_LEGEND_CHANGED,                            LAYER_LEGEND_CHANGED,
40                              LAYER_CHANGED,
41                            LAYER_VISIBILITY_CHANGED)                            LAYER_VISIBILITY_CHANGED)
42    
43      def __init__(self, title, projection = None):      def __init__(self, title, projection = None):
44          """Initialize the map."""          """Initialize the map."""
45          TitledObject.__init__(self, title)          TitledObject.__init__(self, title)
46            Modifiable.__init__(self)
47          self.layers = []          self.layers = []
48          self.label_layer = LabelLayer("Labels")          self.label_layer = LabelLayer(_("Labels"))
49          self.label_layer.Subscribe(CHANGED, self.forward, LAYERS_CHANGED)          self.label_layer.Subscribe(CHANGED, self.forward, MAP_LAYERS_CHANGED)
50          self.projection = projection          self.projection = projection
51    
52      def Destroy(self):      def Destroy(self):
53          for layer in self.layers:          # call Modifiable.Destroy first since it will call
54              layer.Destroy()          # Publisher.Destroy which removes all subscriptions. Otherwise
55            # clearing the layers results in messages to be sent which can
56            # cause problems.
57          Modifiable.Destroy(self)          Modifiable.Destroy(self)
58            self.ClearLayers()
59            self.label_layer.Unsubscribe(CHANGED, self.forward, MAP_LAYERS_CHANGED)
60            self.label_layer.Destroy()
61    
62      def AddLayer(self, layer):      def AddLayer(self, layer):
63            """Append layer to the map on top opf all."""
64          self.layers.append(layer)          self.layers.append(layer)
65            self.subscribe_layer_channels(layer)
66            self.changed(MAP_LAYERS_CHANGED, self)
67            self.changed(MAP_LAYERS_ADDED, self)
68    
69        def RemoveLayer(self, layer):
70            """Remove layer from the map."""
71            self.unsubscribe_layer_channels(layer)
72            self.layers.remove(layer)
73            self.changed(MAP_LAYERS_CHANGED, self)
74            self.changed(MAP_LAYERS_REMOVED, self)
75            layer.Destroy()
76    
77        def CanRemoveLayer(self, layer):
78            """Return true if the layer can be deleted.
79    
80            The default implementation always returns 1. Derived classes
81            should override this method if they have e.g. special layers
82            that the user should not be able to remove.
83            """
84            return 1
85    
86        def ClearLayers(self):
87            """Delete all layers."""
88            for layer in self.layers:
89                self.unsubscribe_layer_channels(layer)
90                layer.Destroy()
91            del self.layers[:]
92            self.label_layer.ClearLabels()
93            self.changed(MAP_LAYERS_CHANGED, self)
94            self.changed(MAP_LAYERS_REMOVED, self)
95    
96        def subscribe_layer_channels(self, layer):
97            """Subscribe to some of layer's channels."""
98          for channel in self.forwarded_channels:          for channel in self.forwarded_channels:
99              layer.Subscribe(channel, self.forward, channel)              layer.Subscribe(channel, self.forward, channel)
         self.changed(LAYERS_CHANGED, self)  
100    
101      def RemoveLayer(self, layer):      def unsubscribe_layer_channels(self, layer):
102            """Unsubscribe to some of layer's channels."""
103          for channel in self.forwarded_channels:          for channel in self.forwarded_channels:
104              layer.Unsubscribe(channel, self.forward, channel)              layer.Unsubscribe(channel, self.forward, channel)
         self.layers.remove(layer)  
         self.changed(LAYERS_CHANGED, self)  
         layer.Destroy()  
105    
106      def LabelLayer(self):      def LabelLayer(self):
107          """Return the Map's label layer"""          """Return the Map's label layer"""
108          return self.label_layer          return self.label_layer
109    
110      def Layers(self):      def Layers(self):
111            """Return the list of layers contained in the map.
112    
113            The list does not include the label layer"""
114          return self.layers          return self.layers
115    
116      def HasLayers(self):      def HasLayers(self):
117            """Return true if the map has at least one shape layer"""
118          return len(self.layers) > 0          return len(self.layers) > 0
119    
120        def MoveLayerToTop(self, layer):
121            """Put the layer on top of the layer stack.
122    
123            If the layer is already at the top do nothing. If the stacking
124            order has been changed, issue a MAP_LAYERS_CHANGED message.
125            """
126            index = self.layers.index(layer)
127            if index < len(self.layers) - 1:
128                del self.layers[index]
129                self.layers.append(layer)
130                self.changed(MAP_LAYERS_CHANGED, self)
131                self.changed(MAP_STACKING_CHANGED, self)
132    
133            
134      def RaiseLayer(self, layer):      def RaiseLayer(self, layer):
135            """Swap the layer with the one above it.
136    
137            If the layer is already at the top do nothing. If the stacking
138            order has been changed, issue a MAP_LAYERS_CHANGED message.
139            """
140          index = self.layers.index(layer)          index = self.layers.index(layer)
141          if index < len(self.layers) - 1:          if index < len(self.layers) - 1:
142              del self.layers[index]              del self.layers[index]
143              self.layers.insert(index + 1, layer)              self.layers.insert(index + 1, layer)
144          self.changed(LAYERS_CHANGED, self)              self.changed(MAP_LAYERS_CHANGED, self)
145                self.changed(MAP_STACKING_CHANGED, self)
146    
147      def LowerLayer(self, layer):      def LowerLayer(self, layer):
148            """Swap the layer with the one below it.
149    
150            If the layer is already at the bottom do nothing. If the
151            stacking order has been changed, issue a MAP_LAYERS_CHANGED message.
152            """
153          index = self.layers.index(layer)          index = self.layers.index(layer)
154          if index > 0:          if index > 0:
155              del self.layers[index]              del self.layers[index]
156              self.layers.insert(index - 1, layer)              self.layers.insert(index - 1, layer)
157          self.changed(LAYERS_CHANGED, self)              self.changed(MAP_LAYERS_CHANGED, self)
158                self.changed(MAP_STACKING_CHANGED, self)
159    
160        def MoveLayerToBottom(self, layer):
161            """Put the layer at the bottom of the stack.
162    
163            If the layer is already at the bottom do nothing. If the
164            stacking order has been changed, issue a MAP_LAYERS_CHANGED message.
165            """
166            index = self.layers.index(layer)
167            if index > 0:
168                del self.layers[index]
169                self.layers.insert(0, layer)
170                self.changed(MAP_LAYERS_CHANGED, self)
171                self.changed(MAP_STACKING_CHANGED, self)
172    
173      def BoundingBox(self):      def BoundingBox(self):
174            """Return the bounding box of the map in Lat/Lon coordinates.
175    
176            Return None if there are no layers or no layer contains any shapes.
177            """
178          if not self.layers:          if not self.layers:
179              return None              return None
180          llx = []          llx = []
# Line 96  class Map(TitledObject, Modifiable): Line 184  class Map(TitledObject, Modifiable):
184          for layer in self.layers:          for layer in self.layers:
185              if layer is self.label_layer:              if layer is self.label_layer:
186                  continue                  continue
187              left, bottom, right, top = layer.LatLongBoundingBox()              # the layer's bbox may be None if it doesn't have any shapes
188              llx.append(left)              bbox = layer.LatLongBoundingBox()
189              lly.append(bottom)              if bbox is not None:
190              urx.append(right)                  left, bottom, right, top = bbox
191              ury.append(top)                  llx.append(left)
192          return (min(llx), min(lly), max(urx), max(ury))                  lly.append(bottom)
193                    urx.append(right)
194                    ury.append(top)
195    
196            # check whether there were any empty layers.
197            if llx:
198                return (min(llx), min(lly), max(urx), max(ury))
199            else:
200                return None
201    
202      def ProjectedBoundingBox(self):      def ProjectedBoundingBox(self):
203            """Return the bounding box of the map in projected coordinates.
204    
205            Return None if there are no layers or no layer contains any shapes.
206            """
207          # This simply returns the rectangle given by the projected          # This simply returns the rectangle given by the projected
208          # corners of the non-projected bbox.          # corners of the non-projected bbox.
209          bbox = self.BoundingBox()          bbox = self.BoundingBox()
# Line 111  class Map(TitledObject, Modifiable): Line 211  class Map(TitledObject, Modifiable):
211              bbox = self.projection.ForwardBBox(bbox)              bbox = self.projection.ForwardBBox(bbox)
212          return bbox          return bbox
213    
214        def GetProjection(self):
215            return self.projection
216    
217      def SetProjection(self, projection):      def SetProjection(self, projection):
218            """Set the projection of the map.
219    
220            Issue a MAP_PROJECTION_CHANGED message."""
221          self.projection = projection          self.projection = projection
222          self.changed(MAP_PROJECTION_CHANGED, self)          self.changed(MAP_PROJECTION_CHANGED, self)
223    
# Line 138  class Map(TitledObject, Modifiable): Line 244  class Map(TitledObject, Modifiable):
244              layer.UnsetModified()              layer.UnsetModified()
245          self.label_layer.UnsetModified()          self.label_layer.UnsetModified()
246    
247        def TreeInfo(self):
248            items = []
249            if self.BoundingBox() != None:
250                items.append(_("Extent (lat-lon): (%g, %g, %g, %g)")
251                             % self.BoundingBox())
252                if self.projection and len(self.projection.params) > 0:
253                    items.append(_("Extent (projected): (%g, %g, %g, %g)")
254                                 % self.ProjectedBoundingBox())
255                    items.append((_("Projection"),
256                                  [str(param)
257                                   for param in self.projection.params]))
258    
259            layers = self.layers[:]
260            layers.reverse()
261            items.extend(layers)
262    
263            return (_("Map: %s") % self.title, items)
264    

Legend:
Removed from v.6  
changed lines
  Added in v.1099

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26