/[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 991 - (hide annotations)
Thu May 22 16:51:44 2003 UTC (21 years, 9 months ago) by frank
Original Path: trunk/thuban/Thuban/Model/map.py
File MIME type: text/x-python
File size: 9097 byte(s)
(Map.TopLayer(), Map.BottomLayer()): New, place
	layer at top/bottom of layer stack.

1 bh 178 # Copyright (c) 2001, 2002 by Intevation GmbH
2 bh 6 # Authors:
3     # Bernhard Herzog <[email protected]>
4     #
5     # This program is free software under the GPL (>=v2)
6     # Read the file COPYING coming with Thuban for details.
7    
8     __version__ = "$Revision$"
9    
10 jonathan 882 from messages import MAP_LAYERS_CHANGED, MAP_PROJECTION_CHANGED, \
11     CHANGED, LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \
12     LAYER_VISIBILITY_CHANGED, LAYER_CHANGED, MAP_STACKING_CHANGED, \
13     MAP_LAYERS_ADDED, MAP_LAYERS_REMOVED
14 bh 6
15 jan 374 from Thuban import _
16    
17 bh 6 from base import TitledObject, Modifiable
18    
19     from label import LabelLayer
20    
21    
22     class Map(TitledObject, Modifiable):
23    
24     """Represent a map. A map is simply a list of layers.
25    
26     Map objects send the following message types:
27    
28     TITLE_CHANGED -- The title has changed. Parameter: the map.
29    
30 jonathan 546 MAP_LAYERS_CHANGED -- Layers were added, removed or rearranged.
31 bh 6 Parameters: the map
32    
33     MAP_PROJECTION_CHANGED -- the map's projection has changed.
34     Parameter: the map
35     """
36    
37 bh 319 forwarded_channels = (CHANGED,
38     LAYER_PROJECTION_CHANGED,
39 bh 6 LAYER_LEGEND_CHANGED,
40 jonathan 559 LAYER_CHANGED,
41 bh 6 LAYER_VISIBILITY_CHANGED)
42    
43     def __init__(self, title, projection = None):
44     """Initialize the map."""
45     TitledObject.__init__(self, title)
46 bh 319 Modifiable.__init__(self)
47 bh 6 self.layers = []
48 jan 374 self.label_layer = LabelLayer(_("Labels"))
49 jonathan 546 self.label_layer.Subscribe(CHANGED, self.forward, MAP_LAYERS_CHANGED)
50 bh 6 self.projection = projection
51    
52     def Destroy(self):
53 bh 249 # call Modifiable.Destroy first since it will call
54     # 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)
58     self.ClearLayers()
59 jonathan 546 self.label_layer.Unsubscribe(CHANGED, self.forward, MAP_LAYERS_CHANGED)
60 bh 249 self.label_layer.Destroy()
61 bh 6
62     def AddLayer(self, layer):
63 bh 249 """Append layer to the map on top opf all."""
64 bh 6 self.layers.append(layer)
65 bh 245 self.subscribe_layer_channels(layer)
66 jonathan 546 self.changed(MAP_LAYERS_CHANGED, self)
67     self.changed(MAP_LAYERS_ADDED, self)
68 bh 6
69     def RemoveLayer(self, layer):
70 bh 249 """Remove layer from the map."""
71 bh 245 self.unsubscribe_layer_channels(layer)
72 bh 6 self.layers.remove(layer)
73 jonathan 546 self.changed(MAP_LAYERS_CHANGED, self)
74     self.changed(MAP_LAYERS_REMOVED, self)
75 bh 6 layer.Destroy()
76    
77 bh 298 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 bh 249 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 jonathan 546 self.changed(MAP_LAYERS_CHANGED, self)
94     self.changed(MAP_LAYERS_REMOVED, self)
95 bh 249
96 bh 245 def subscribe_layer_channels(self, layer):
97     """Subscribe to some of layer's channels."""
98     for channel in self.forwarded_channels:
99     layer.Subscribe(channel, self.forward, channel)
100    
101     def unsubscribe_layer_channels(self, layer):
102     """Unsubscribe to some of layer's channels."""
103     for channel in self.forwarded_channels:
104     layer.Unsubscribe(channel, self.forward, channel)
105    
106 bh 6 def LabelLayer(self):
107     """Return the Map's label layer"""
108     return self.label_layer
109    
110     def Layers(self):
111 bh 249 """Return the list of layers contained in the map.
112    
113     The list does not include the label layer"""
114 bh 6 return self.layers
115    
116     def HasLayers(self):
117 bh 249 """Return true if the map has at least one shape layer"""
118 bh 6 return len(self.layers) > 0
119    
120 frank 991 def TopLayer(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 bh 6 def RaiseLayer(self, layer):
135 bh 249 """Swap the layer with the one above it.
136    
137     If the layer is already at the top do nothing. If the stacking
138 jonathan 546 order has been changed, issue a MAP_LAYERS_CHANGED message.
139 bh 249 """
140 bh 6 index = self.layers.index(layer)
141     if index < len(self.layers) - 1:
142     del self.layers[index]
143     self.layers.insert(index + 1, layer)
144 jonathan 546 self.changed(MAP_LAYERS_CHANGED, self)
145     self.changed(MAP_STACKING_CHANGED, self)
146 bh 6
147     def LowerLayer(self, layer):
148 bh 249 """Swap the layer with the one below it.
149    
150     If the layer is already at the bottom do nothing. If the
151 jonathan 546 stacking order has been changed, issue a MAP_LAYERS_CHANGED message.
152 bh 249 """
153 bh 6 index = self.layers.index(layer)
154     if index > 0:
155     del self.layers[index]
156     self.layers.insert(index - 1, layer)
157 jonathan 546 self.changed(MAP_LAYERS_CHANGED, self)
158     self.changed(MAP_STACKING_CHANGED, self)
159 bh 6
160 frank 991 def BottomLayer(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 bh 6 def BoundingBox(self):
174 bh 249 """Return the bounding box of the map in Lat/Lon coordinates.
175 bh 178
176     Return None if there are no layers or no layer contains any shapes.
177     """
178 bh 6 if not self.layers:
179     return None
180     llx = []
181     lly = []
182     urx = []
183     ury = []
184     for layer in self.layers:
185     if layer is self.label_layer:
186     continue
187 jonathan 931 # the layer's bbox may be None if it doesn't have any shapes
188 bh 178 bbox = layer.LatLongBoundingBox()
189     if bbox is not None:
190     left, bottom, right, top = bbox
191     llx.append(left)
192     lly.append(bottom)
193     urx.append(right)
194     ury.append(top)
195 bh 6
196 bh 178 # 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 bh 6 def ProjectedBoundingBox(self):
203 bh 249 """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 bh 6 # This simply returns the rectangle given by the projected
208     # corners of the non-projected bbox.
209     bbox = self.BoundingBox()
210     if bbox is not None and self.projection is not None:
211     bbox = self.projection.ForwardBBox(bbox)
212     return bbox
213    
214 jonathan 707 def GetProjection(self):
215     return self.projection
216    
217 bh 6 def SetProjection(self, projection):
218 bh 249 """Set the projection of the map.
219    
220     Issue a MAP_PROJECTION_CHANGED message."""
221 bh 6 self.projection = projection
222     self.changed(MAP_PROJECTION_CHANGED, self)
223    
224     def forward(self, *args):
225     """Reissue events"""
226     if len(args) > 1:
227     args = (args[-1],) + args[:-1]
228     apply(self.issue, args)
229    
230     def WasModified(self):
231     """Return true if the map or one of the layers was modified"""
232     if self.modified:
233     return 1
234     else:
235     for layer in self.layers:
236     if layer.WasModified():
237     return 1
238     return self.label_layer.WasModified()
239    
240     def UnsetModified(self):
241     """Unset the modified flag of the map and the layers"""
242     Modifiable.UnsetModified(self)
243     for layer in self.layers:
244     layer.UnsetModified()
245     self.label_layer.UnsetModified()
246    
247 bh 217 def TreeInfo(self):
248     items = []
249     if self.BoundingBox() != None:
250 jan 374 items.append(_("Extent (lat-lon): (%g, %g, %g, %g)")
251 bh 217 % self.BoundingBox())
252 bh 231 if self.projection and len(self.projection.params) > 0:
253 jan 374 items.append(_("Extent (projected): (%g, %g, %g, %g)")
254 bh 231 % self.ProjectedBoundingBox())
255 jan 374 items.append((_("Projection"),
256 bh 231 [str(param)
257     for param in self.projection.params]))
258 bh 6
259 bh 217 layers = self.layers[:]
260     layers.reverse()
261     items.extend(layers)
262    
263 jan 374 return (_("Map: %s") % self.title, items)
264 bh 217

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26