/[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 319 by bh, Fri Sep 13 14:21:24 2002 UTC revision 2564 by jan, Wed Feb 16 23:14:35 2005 UTC
# Line 1  Line 1 
1  # Copyright (c) 2001, 2002 by Intevation GmbH  # Copyright (c) 2001-2003, 2005 by Intevation GmbH
2  # Authors:  # Authors:
3  # Bernhard Herzog <[email protected]>  # Bernhard Herzog <[email protected]>
4    # Jonathan Coles <[email protected]>
5  #  #
6  # This program is free software under the GPL (>=v2)  # This program is free software under the GPL (>=v2)
7  # Read the file COPYING coming with Thuban for details.  # Read the file COPYING coming with Thuban for details.
8    
9  __version__ = "$Revision$"  __version__ = "$Revision$"
10    
11  from messages import LAYERS_CHANGED, MAP_PROJECTION_CHANGED, \  from messages import MAP_LAYERS_CHANGED, MAP_PROJECTION_CHANGED, \
12       CHANGED, LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \       CHANGED, LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \
13       LAYER_VISIBILITY_CHANGED       LAYER_VISIBILITY_CHANGED, LAYER_CHANGED, MAP_STACKING_CHANGED, \
14         MAP_LAYERS_ADDED, MAP_LAYERS_REMOVED
15    
16    from Thuban import _
17    
18  from base import TitledObject, Modifiable  from base import TitledObject, Modifiable
19    
20  from label import LabelLayer  from label import LabelLayer
21    
22    
   
23  class Map(TitledObject, Modifiable):  class Map(TitledObject, Modifiable):
24    
25      """Represent a map. A map is simply a list of layers.      """Represent a map. A map is a list of layers. Additionally
26        there is a special label layer containing all labels that
27        are defined for the map.
28    
29      Map objects send the following message types:      Map objects send the following message types:
30    
31          TITLE_CHANGED -- The title has changed. Parameter: the map.          TITLE_CHANGED -- The title has changed. Parameter: the map.
32    
33          LAYERS_CHANGED -- Layers were added, removed or rearranged.          MAP_LAYERS_CHANGED -- Layers were added, removed or rearranged.
34                          Parameters: the map                          Parameters: the map
35    
36          MAP_PROJECTION_CHANGED -- the map's projection has changed.          MAP_PROJECTION_CHANGED -- the map's projection has changed.
# Line 35  class Map(TitledObject, Modifiable): Line 40  class Map(TitledObject, Modifiable):
40      forwarded_channels = (CHANGED,      forwarded_channels = (CHANGED,
41                            LAYER_PROJECTION_CHANGED,                            LAYER_PROJECTION_CHANGED,
42                            LAYER_LEGEND_CHANGED,                            LAYER_LEGEND_CHANGED,
43                              LAYER_CHANGED,
44                            LAYER_VISIBILITY_CHANGED)                            LAYER_VISIBILITY_CHANGED)
45    
46      def __init__(self, title, projection = None):      def __init__(self, title, projection = None):
# Line 42  class Map(TitledObject, Modifiable): Line 48  class Map(TitledObject, Modifiable):
48          TitledObject.__init__(self, title)          TitledObject.__init__(self, title)
49          Modifiable.__init__(self)          Modifiable.__init__(self)
50          self.layers = []          self.layers = []
51          self.label_layer = LabelLayer("Labels")          self.label_layer = LabelLayer(_("Labels"))
52          self.label_layer.Subscribe(CHANGED, self.forward, LAYERS_CHANGED)          self.label_layer.Subscribe(CHANGED, self.forward, MAP_LAYERS_CHANGED)
53          self.projection = projection          self.projection = projection
54    
55      def Destroy(self):      def Destroy(self):
56          # call Modifiable.Destroy first since it will call          """Destroys the map object with all layers including
57          # Publisher.Destroy which removes all subscriptions. Otherwise          the label layer.
58          # clearing the layers results in messages to be sent which can  
59          # cause problems.          Calls Modifiable.Destroy first since it will call
60            Publisher.Destroy which removes all subscriptions. Otherwise
61            clearing the layers results in messages to be sent which can
62            cause problems.
63            """
64          Modifiable.Destroy(self)          Modifiable.Destroy(self)
65          self.ClearLayers()          self.ClearLayers()
66          self.label_layer.Unsubscribe(CHANGED, self.forward, LAYERS_CHANGED)          self.label_layer.Unsubscribe(CHANGED, self.forward, MAP_LAYERS_CHANGED)
67          self.label_layer.Destroy()          self.label_layer.Destroy()
68    
69      def AddLayer(self, layer):      def AddLayer(self, layer):
70          """Append layer to the map on top opf all."""          """Append layer to the map on top of all."""
71          self.layers.append(layer)          self.layers.append(layer)
72          self.subscribe_layer_channels(layer)          self.subscribe_layer_channels(layer)
73          self.changed(LAYERS_CHANGED, self)          self.changed(MAP_LAYERS_CHANGED, self)
74            self.changed(MAP_LAYERS_ADDED, self)
75    
76      def RemoveLayer(self, layer):      def RemoveLayer(self, layer):
77          """Remove layer from the map."""          """Remove layer from the map.
78            This can not be applied for the label layer of the map.
79            """
80          self.unsubscribe_layer_channels(layer)          self.unsubscribe_layer_channels(layer)
81          self.layers.remove(layer)          self.layers.remove(layer)
82          self.changed(LAYERS_CHANGED, self)          self.changed(MAP_LAYERS_CHANGED, self)
83            self.changed(MAP_LAYERS_REMOVED, self)
84          layer.Destroy()          layer.Destroy()
85    
86      def CanRemoveLayer(self, layer):      def CanRemoveLayer(self, layer):
# Line 79  class Map(TitledObject, Modifiable): Line 93  class Map(TitledObject, Modifiable):
93          return 1          return 1
94    
95      def ClearLayers(self):      def ClearLayers(self):
96          """Delete all layers."""          """Delete all layers and also remove all labels from the
97            label layer.
98            """
99          for layer in self.layers:          for layer in self.layers:
100              self.unsubscribe_layer_channels(layer)              self.unsubscribe_layer_channels(layer)
101              layer.Destroy()              layer.Destroy()
102          del self.layers[:]          del self.layers[:]
103          self.label_layer.ClearLabels()          self.label_layer.ClearLabels()
104          self.changed(LAYERS_CHANGED, self)          self.changed(MAP_LAYERS_CHANGED, self)
105            self.changed(MAP_LAYERS_REMOVED, self)
106    
107      def subscribe_layer_channels(self, layer):      def subscribe_layer_channels(self, layer):
108          """Subscribe to some of layer's channels."""          """Subscribe to some of layer's channels."""
# Line 104  class Map(TitledObject, Modifiable): Line 121  class Map(TitledObject, Modifiable):
121      def Layers(self):      def Layers(self):
122          """Return the list of layers contained in the map.          """Return the list of layers contained in the map.
123    
124          The list does not include the label layer"""          The list does not include the label layer which
125            can be retrieved by a separate method."""
126          return self.layers          return self.layers
127    
128      def HasLayers(self):      def HasLayers(self):
129          """Return true if the map has at least one shape layer"""          """Return true if the map has at least one layer other
130            than the label layer."""
131          return len(self.layers) > 0          return len(self.layers) > 0
132    
133        def MoveLayerToTop(self, layer):
134            """Put the layer on top of the layer stack. This can not
135            be applied to the label layer.
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)
141            if index < len(self.layers) - 1:
142                del self.layers[index]
143                self.layers.append(layer)
144                self.changed(MAP_LAYERS_CHANGED, self)
145                self.changed(MAP_STACKING_CHANGED, self)
146    
147      def RaiseLayer(self, layer):      def RaiseLayer(self, layer):
148          """Swap the layer with the one above it.          """Swap the layer with the one above it. This does
149            not apply to the label layer.
150    
151          If the layer is already at the top do nothing. If the stacking          If the layer is already at the top do nothing. If the stacking
152          order has been changed, issue a LAYERS_CHANGED message.          order has been changed, issue a MAP_LAYERS_CHANGED message.
153          """          """
154          index = self.layers.index(layer)          index = self.layers.index(layer)
155          if index < len(self.layers) - 1:          if index < len(self.layers) - 1:
156              del self.layers[index]              del self.layers[index]
157              self.layers.insert(index + 1, layer)              self.layers.insert(index + 1, layer)
158              self.changed(LAYERS_CHANGED, self)              self.changed(MAP_LAYERS_CHANGED, self)
159                self.changed(MAP_STACKING_CHANGED, self)
160    
161      def LowerLayer(self, layer):      def LowerLayer(self, layer):
162          """Swap the layer with the one below it.          """Swap the layer with the one below it. This does
163            not apply to the label layer.
164    
165          If the layer is already at the bottom do nothing. If the          If the layer is already at the bottom do nothing. If the
166          stacking order has been changed, issue a LAYERS_CHANGED message.          stacking order has been changed, issue a MAP_LAYERS_CHANGED message.
167          """          """
168          index = self.layers.index(layer)          index = self.layers.index(layer)
169          if index > 0:          if index > 0:
170              del self.layers[index]              del self.layers[index]
171              self.layers.insert(index - 1, layer)              self.layers.insert(index - 1, layer)
172              self.changed(LAYERS_CHANGED, self)              self.changed(MAP_LAYERS_CHANGED, self)
173                self.changed(MAP_STACKING_CHANGED, self)
174    
175        def MoveLayerToBottom(self, layer):
176            """Put the layer at the bottom of the stack. This does
177            not apply to the label layer.
178    
179            If the layer is already at the bottom do nothing. If the
180            stacking order has been changed, issue a MAP_LAYERS_CHANGED message.
181            """
182            index = self.layers.index(layer)
183            if index > 0:
184                del self.layers[index]
185                self.layers.insert(0, layer)
186                self.changed(MAP_LAYERS_CHANGED, self)
187                self.changed(MAP_STACKING_CHANGED, self)
188    
189      def BoundingBox(self):      def BoundingBox(self):
190          """Return the bounding box of the map in Lat/Lon coordinates.          """Return the bounding box of the map in Lat/Lon coordinates.
191            The label layer is not considered for the computation of the
192            bounding box.
193    
194          Return None if there are no layers or no layer contains any shapes.          Return None if there are no layers (except the label layer) or
195            no layer contains any shapes.
196          """          """
197          if not self.layers:          if not self.layers:
198              return None              return None
# Line 147  class Map(TitledObject, Modifiable): Line 201  class Map(TitledObject, Modifiable):
201          urx = []          urx = []
202          ury = []          ury = []
203          for layer in self.layers:          for layer in self.layers:
204              if layer is self.label_layer:              # the layer's bbox may be None if it doesn't have any shapes
                 continue  
             # the layer's bbox may be None if it doesn't have any layers  
205              bbox = layer.LatLongBoundingBox()              bbox = layer.LatLongBoundingBox()
206              if bbox is not None:              if bbox is not None:
207                  left, bottom, right, top = bbox                  left, bottom, right, top = bbox
# Line 166  class Map(TitledObject, Modifiable): Line 218  class Map(TitledObject, Modifiable):
218    
219      def ProjectedBoundingBox(self):      def ProjectedBoundingBox(self):
220          """Return the bounding box of the map in projected coordinates.          """Return the bounding box of the map in projected coordinates.
221            The label layer is not considered for the computation of the
222            bounding box.
223    
224          Return None if there are no layers or no layer contains any shapes.          Return None if there are no layers (except the label layer) or
225            no layer contains any shapes.
226          """          """
227          # This simply returns the rectangle given by the projected          # This simply returns the rectangle given by the projected
228          # corners of the non-projected bbox.          # corners of the non-projected bbox.
# Line 176  class Map(TitledObject, Modifiable): Line 231  class Map(TitledObject, Modifiable):
231              bbox = self.projection.ForwardBBox(bbox)              bbox = self.projection.ForwardBBox(bbox)
232          return bbox          return bbox
233    
234        def GetProjection(self):
235            """Return the projection of the map."""
236            return self.projection
237    
238      def SetProjection(self, projection):      def SetProjection(self, projection):
239          """Set the projection of the map.          """Set the projection of the map.
240    
241          Issue a MAP_PROJECTION_CHANGED message."""          Issue a MAP_PROJECTION_CHANGED message."""
242            old_proj = self.projection
243          self.projection = projection          self.projection = projection
244          self.changed(MAP_PROJECTION_CHANGED, self)          self.changed(MAP_PROJECTION_CHANGED, self, old_proj)
245    
246      def forward(self, *args):      def forward(self, *args):
247          """Reissue events"""          """Reissue events"""
# Line 207  class Map(TitledObject, Modifiable): Line 267  class Map(TitledObject, Modifiable):
267          self.label_layer.UnsetModified()          self.label_layer.UnsetModified()
268    
269      def TreeInfo(self):      def TreeInfo(self):
270            """Return a tuple of (title, tupel) describing the contents
271            of the object in a tree-structure.
272            """
273          items = []          items = []
274          if self.BoundingBox() != None:          if self.BoundingBox() != None:
275              items.append("Extent (lat-lon): (%g, %g, %g, %g)"              items.append(_("Extent (lat-lon): (%g, %g, %g, %g)")
276                           % self.BoundingBox())                           % self.BoundingBox())
277              if self.projection and len(self.projection.params) > 0:              if self.projection and len(self.projection.params) > 0:
278                  items.append("Extent (projected): (%g, %g, %g, %g)"                  items.append(_("Extent (projected): (%g, %g, %g, %g)")
279                               % self.ProjectedBoundingBox())                               % self.ProjectedBoundingBox())
280                  items.append(("Projection",                  items.append((_("Projection"),
281                                [str(param)                                [str(param)
282                                 for param in self.projection.params]))                                 for param in self.projection.params]))
283    
284          layers = self.layers[:]          layers = self.layers[:]
285          layers.reverse()          layers.reverse()
286          items.extend(layers)          items.extend(layers)
287            items.append(self.label_layer)
288    
289          return ("Map: %s" % self.title, items)          return (_("Map: %s") % self.title, items)
   

Legend:
Removed from v.319  
changed lines
  Added in v.2564

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26