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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2564 - (hide annotations)
Wed Feb 16 23:14:35 2005 UTC (20 years ago) by jan
Original Path: trunk/thuban/Thuban/Model/map.py
File MIME type: text/x-python
File size: 10187 byte(s)
(Map, Map.Destroy, Map.RemoveLayer, Map.ClearLayers,
Map.Layers, Map.HasLayers, Map.MoveLayerToTop,
Map.RaiseLayer, Map.LowerLayer, Map.MoveLayerToBottom,
Map.ProjectedBoundingBox, Map.GetProjection): Improved/added
doc string.
(Map.BoundingBox): Removed superfluous test for label_layer
and improved doc string.
(Map.TreeInfo): Added label_layer and improved sdo string.

1 jan 2564 # Copyright (c) 2001-2003, 2005 by Intevation GmbH
2 bh 6 # Authors:
3     # Bernhard Herzog <[email protected]>
4 jan 2564 # Jonathan Coles <[email protected]>
5 bh 6 #
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 jonathan 882 from messages import MAP_LAYERS_CHANGED, MAP_PROJECTION_CHANGED, \
12     CHANGED, LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \
13     LAYER_VISIBILITY_CHANGED, LAYER_CHANGED, MAP_STACKING_CHANGED, \
14     MAP_LAYERS_ADDED, MAP_LAYERS_REMOVED
15 bh 6
16 jan 374 from Thuban import _
17    
18 bh 6 from base import TitledObject, Modifiable
19    
20     from label import LabelLayer
21    
22    
23     class Map(TitledObject, Modifiable):
24    
25 jan 2564 """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 bh 6
29     Map objects send the following message types:
30    
31     TITLE_CHANGED -- The title has changed. Parameter: the map.
32    
33 jonathan 546 MAP_LAYERS_CHANGED -- Layers were added, removed or rearranged.
34 bh 6 Parameters: the map
35    
36     MAP_PROJECTION_CHANGED -- the map's projection has changed.
37     Parameter: the map
38     """
39    
40 bh 319 forwarded_channels = (CHANGED,
41     LAYER_PROJECTION_CHANGED,
42 bh 6 LAYER_LEGEND_CHANGED,
43 jonathan 559 LAYER_CHANGED,
44 bh 6 LAYER_VISIBILITY_CHANGED)
45    
46     def __init__(self, title, projection = None):
47     """Initialize the map."""
48     TitledObject.__init__(self, title)
49 bh 319 Modifiable.__init__(self)
50 bh 6 self.layers = []
51 jan 374 self.label_layer = LabelLayer(_("Labels"))
52 jonathan 546 self.label_layer.Subscribe(CHANGED, self.forward, MAP_LAYERS_CHANGED)
53 bh 6 self.projection = projection
54    
55     def Destroy(self):
56 jan 2564 """Destroys the map object with all layers including
57     the label layer.
58    
59     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 bh 249 Modifiable.Destroy(self)
65     self.ClearLayers()
66 jonathan 546 self.label_layer.Unsubscribe(CHANGED, self.forward, MAP_LAYERS_CHANGED)
67 bh 249 self.label_layer.Destroy()
68 bh 6
69     def AddLayer(self, layer):
70 jonathan 1388 """Append layer to the map on top of all."""
71 bh 6 self.layers.append(layer)
72 bh 245 self.subscribe_layer_channels(layer)
73 jonathan 546 self.changed(MAP_LAYERS_CHANGED, self)
74     self.changed(MAP_LAYERS_ADDED, self)
75 bh 6
76     def RemoveLayer(self, layer):
77 jan 2564 """Remove layer from the map.
78     This can not be applied for the label layer of the map.
79     """
80 bh 245 self.unsubscribe_layer_channels(layer)
81 bh 6 self.layers.remove(layer)
82 jonathan 546 self.changed(MAP_LAYERS_CHANGED, self)
83     self.changed(MAP_LAYERS_REMOVED, self)
84 bh 6 layer.Destroy()
85    
86 bh 298 def CanRemoveLayer(self, layer):
87     """Return true if the layer can be deleted.
88    
89     The default implementation always returns 1. Derived classes
90     should override this method if they have e.g. special layers
91     that the user should not be able to remove.
92     """
93     return 1
94    
95 bh 249 def ClearLayers(self):
96 jan 2564 """Delete all layers and also remove all labels from the
97     label layer.
98     """
99 bh 249 for layer in self.layers:
100     self.unsubscribe_layer_channels(layer)
101     layer.Destroy()
102     del self.layers[:]
103     self.label_layer.ClearLabels()
104 jonathan 546 self.changed(MAP_LAYERS_CHANGED, self)
105     self.changed(MAP_LAYERS_REMOVED, self)
106 bh 249
107 bh 245 def subscribe_layer_channels(self, layer):
108     """Subscribe to some of layer's channels."""
109     for channel in self.forwarded_channels:
110     layer.Subscribe(channel, self.forward, channel)
111    
112     def unsubscribe_layer_channels(self, layer):
113     """Unsubscribe to some of layer's channels."""
114     for channel in self.forwarded_channels:
115     layer.Unsubscribe(channel, self.forward, channel)
116    
117 bh 6 def LabelLayer(self):
118     """Return the Map's label layer"""
119     return self.label_layer
120    
121     def Layers(self):
122 bh 249 """Return the list of layers contained in the map.
123    
124 jan 2564 The list does not include the label layer which
125     can be retrieved by a separate method."""
126 bh 6 return self.layers
127    
128     def HasLayers(self):
129 jan 2564 """Return true if the map has at least one layer other
130     than the label layer."""
131 bh 6 return len(self.layers) > 0
132    
133 jonathan 1099 def MoveLayerToTop(self, layer):
134 jan 2564 """Put the layer on top of the layer stack. This can not
135     be applied to the label layer.
136 frank 991
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 bh 6 def RaiseLayer(self, layer):
148 jan 2564 """Swap the layer with the one above it. This does
149     not apply to the label layer.
150 bh 249
151     If the layer is already at the top do nothing. If the stacking
152 jonathan 546 order has been changed, issue a MAP_LAYERS_CHANGED message.
153 bh 249 """
154 bh 6 index = self.layers.index(layer)
155     if index < len(self.layers) - 1:
156     del self.layers[index]
157     self.layers.insert(index + 1, layer)
158 jonathan 546 self.changed(MAP_LAYERS_CHANGED, self)
159     self.changed(MAP_STACKING_CHANGED, self)
160 bh 6
161     def LowerLayer(self, layer):
162 jan 2564 """Swap the layer with the one below it. This does
163     not apply to the label layer.
164 bh 249
165     If the layer is already at the bottom do nothing. If the
166 jonathan 546 stacking order has been changed, issue a MAP_LAYERS_CHANGED message.
167 bh 249 """
168 bh 6 index = self.layers.index(layer)
169     if index > 0:
170     del self.layers[index]
171     self.layers.insert(index - 1, layer)
172 jonathan 546 self.changed(MAP_LAYERS_CHANGED, self)
173     self.changed(MAP_STACKING_CHANGED, self)
174 bh 6
175 jonathan 1099 def MoveLayerToBottom(self, layer):
176 jan 2564 """Put the layer at the bottom of the stack. This does
177     not apply to the label layer.
178 frank 991
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 bh 6 def BoundingBox(self):
190 bh 249 """Return the bounding box of the map in Lat/Lon coordinates.
191 jan 2564 The label layer is not considered for the computation of the
192     bounding box.
193 bh 178
194 jan 2564 Return None if there are no layers (except the label layer) or
195     no layer contains any shapes.
196 bh 178 """
197 bh 6 if not self.layers:
198     return None
199     llx = []
200     lly = []
201     urx = []
202     ury = []
203     for layer in self.layers:
204 jonathan 931 # the layer's bbox may be None if it doesn't have any shapes
205 bh 178 bbox = layer.LatLongBoundingBox()
206     if bbox is not None:
207     left, bottom, right, top = bbox
208     llx.append(left)
209     lly.append(bottom)
210     urx.append(right)
211     ury.append(top)
212 bh 6
213 bh 178 # check whether there were any empty layers.
214     if llx:
215     return (min(llx), min(lly), max(urx), max(ury))
216     else:
217     return None
218    
219 bh 6 def ProjectedBoundingBox(self):
220 bh 249 """Return the bounding box of the map in projected coordinates.
221 jan 2564 The label layer is not considered for the computation of the
222     bounding box.
223 bh 249
224 jan 2564 Return None if there are no layers (except the label layer) or
225     no layer contains any shapes.
226 bh 249 """
227 bh 6 # This simply returns the rectangle given by the projected
228     # corners of the non-projected bbox.
229     bbox = self.BoundingBox()
230     if bbox is not None and self.projection is not None:
231     bbox = self.projection.ForwardBBox(bbox)
232     return bbox
233    
234 jonathan 707 def GetProjection(self):
235 jan 2564 """Return the projection of the map."""
236 jonathan 707 return self.projection
237    
238 bh 6 def SetProjection(self, projection):
239 bh 249 """Set the projection of the map.
240    
241     Issue a MAP_PROJECTION_CHANGED message."""
242 jonathan 1388 old_proj = self.projection
243 bh 6 self.projection = projection
244 jonathan 1388 self.changed(MAP_PROJECTION_CHANGED, self, old_proj)
245 bh 6
246     def forward(self, *args):
247     """Reissue events"""
248     if len(args) > 1:
249     args = (args[-1],) + args[:-1]
250     apply(self.issue, args)
251    
252     def WasModified(self):
253     """Return true if the map or one of the layers was modified"""
254     if self.modified:
255     return 1
256     else:
257     for layer in self.layers:
258     if layer.WasModified():
259     return 1
260     return self.label_layer.WasModified()
261    
262     def UnsetModified(self):
263     """Unset the modified flag of the map and the layers"""
264     Modifiable.UnsetModified(self)
265     for layer in self.layers:
266     layer.UnsetModified()
267     self.label_layer.UnsetModified()
268    
269 bh 217 def TreeInfo(self):
270 jan 2564 """Return a tuple of (title, tupel) describing the contents
271     of the object in a tree-structure.
272     """
273 bh 217 items = []
274     if self.BoundingBox() != None:
275 jan 374 items.append(_("Extent (lat-lon): (%g, %g, %g, %g)")
276 bh 217 % self.BoundingBox())
277 bh 231 if self.projection and len(self.projection.params) > 0:
278 jan 374 items.append(_("Extent (projected): (%g, %g, %g, %g)")
279 bh 231 % self.ProjectedBoundingBox())
280 jan 374 items.append((_("Projection"),
281 bh 231 [str(param)
282     for param in self.projection.params]))
283 bh 6
284 bh 217 layers = self.layers[:]
285     layers.reverse()
286     items.extend(layers)
287 jan 2564 items.append(self.label_layer)
288 bh 217
289 jan 374 return (_("Map: %s") % self.title, items)

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26