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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 249 - (show annotations)
Tue Jul 30 14:17:33 2002 UTC (22 years, 7 months ago) by bh
Original Path: trunk/thuban/Thuban/Model/map.py
File MIME type: text/x-python
File size: 7219 byte(s)
(Map.ClearLayers): New method to delete all
layers.
(Map.Destroy): Destroy the label_layer as well and call the
inherited Desatroymethod first so that no more messages are
issued.
(Map.RaiseLayer, Map.LowerLayer): Only issue LAYERS_CHANGED
message if the stacking order actually has changed. Add
doc-strings.
(Map.BoundingBox): Correct the doc-string.
(Map.AddLayer, Map.RemoveLayer, Map.Layers, Map.HasLayers)
(Map.ProjectedBoundingBox, Map.SetProjection): Add doc-strings.

1 # Copyright (c) 2001, 2002 by Intevation GmbH
2 # 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 from messages import LAYERS_CHANGED, MAP_PROJECTION_CHANGED, \
11 CHANGED, LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \
12 LAYER_VISIBILITY_CHANGED
13
14 from base import TitledObject, Modifiable
15
16 from label import LabelLayer
17
18
19
20 class Map(TitledObject, Modifiable):
21
22 """Represent a map. A map is simply a list of layers.
23
24 Map objects send the following message types:
25
26 TITLE_CHANGED -- The title has changed. Parameter: the map.
27
28 LAYERS_CHANGED -- Layers were added, removed or rearranged.
29 Parameters: the map
30
31 MAP_PROJECTION_CHANGED -- the map's projection has changed.
32 Parameter: the map
33 """
34
35 forwarded_channels = (LAYER_PROJECTION_CHANGED,
36 LAYER_LEGEND_CHANGED,
37 LAYER_VISIBILITY_CHANGED)
38
39 def __init__(self, title, projection = None):
40 """Initialize the map."""
41 TitledObject.__init__(self, title)
42 self.layers = []
43 self.label_layer = LabelLayer("Labels")
44 self.label_layer.Subscribe(CHANGED, self.forward, LAYERS_CHANGED)
45 self.projection = projection
46
47 def Destroy(self):
48 # call Modifiable.Destroy first since it will call
49 # Publisher.Destroy which removes all subscriptions. Otherwise
50 # clearing the layers results in messages to be sent which can
51 # cause problems.
52 Modifiable.Destroy(self)
53 self.ClearLayers()
54 self.label_layer.Unsubscribe(CHANGED, self.forward, LAYERS_CHANGED)
55 self.label_layer.Destroy()
56
57 def AddLayer(self, layer):
58 """Append layer to the map on top opf all."""
59 self.layers.append(layer)
60 self.subscribe_layer_channels(layer)
61 self.changed(LAYERS_CHANGED, self)
62
63 def RemoveLayer(self, layer):
64 """Remove layer from the map."""
65 self.unsubscribe_layer_channels(layer)
66 self.layers.remove(layer)
67 self.changed(LAYERS_CHANGED, self)
68 layer.Destroy()
69
70 def ClearLayers(self):
71 """Delete all layers."""
72 for layer in self.layers:
73 self.unsubscribe_layer_channels(layer)
74 layer.Destroy()
75 del self.layers[:]
76 self.label_layer.ClearLabels()
77 self.changed(LAYERS_CHANGED, self)
78
79 def subscribe_layer_channels(self, layer):
80 """Subscribe to some of layer's channels."""
81 for channel in self.forwarded_channels:
82 layer.Subscribe(channel, self.forward, channel)
83
84 def unsubscribe_layer_channels(self, layer):
85 """Unsubscribe to some of layer's channels."""
86 for channel in self.forwarded_channels:
87 layer.Unsubscribe(channel, self.forward, channel)
88
89 def LabelLayer(self):
90 """Return the Map's label layer"""
91 return self.label_layer
92
93 def Layers(self):
94 """Return the list of layers contained in the map.
95
96 The list does not include the label layer"""
97 return self.layers
98
99 def HasLayers(self):
100 """Return true if the map has at least one shape layer"""
101 return len(self.layers) > 0
102
103 def RaiseLayer(self, layer):
104 """Swap the layer with the one above it.
105
106 If the layer is already at the top do nothing. If the stacking
107 order has been changed, issue a LAYERS_CHANGED message.
108 """
109 index = self.layers.index(layer)
110 if index < len(self.layers) - 1:
111 del self.layers[index]
112 self.layers.insert(index + 1, layer)
113 self.changed(LAYERS_CHANGED, self)
114
115 def LowerLayer(self, layer):
116 """Swap the layer with the one below it.
117
118 If the layer is already at the bottom do nothing. If the
119 stacking order has been changed, issue a LAYERS_CHANGED message.
120 """
121 index = self.layers.index(layer)
122 if index > 0:
123 del self.layers[index]
124 self.layers.insert(index - 1, layer)
125 self.changed(LAYERS_CHANGED, self)
126
127 def BoundingBox(self):
128 """Return the bounding box of the map in Lat/Lon coordinates.
129
130 Return None if there are no layers or no layer contains any shapes.
131 """
132 if not self.layers:
133 return None
134 llx = []
135 lly = []
136 urx = []
137 ury = []
138 for layer in self.layers:
139 if layer is self.label_layer:
140 continue
141 # the layer's bbox may be None if it doesn't have any layers
142 bbox = layer.LatLongBoundingBox()
143 if bbox is not None:
144 left, bottom, right, top = bbox
145 llx.append(left)
146 lly.append(bottom)
147 urx.append(right)
148 ury.append(top)
149
150 # check whether there were any empty layers.
151 if llx:
152 return (min(llx), min(lly), max(urx), max(ury))
153 else:
154 return None
155
156 def ProjectedBoundingBox(self):
157 """Return the bounding box of the map in projected coordinates.
158
159 Return None if there are no layers or no layer contains any shapes.
160 """
161 # This simply returns the rectangle given by the projected
162 # corners of the non-projected bbox.
163 bbox = self.BoundingBox()
164 if bbox is not None and self.projection is not None:
165 bbox = self.projection.ForwardBBox(bbox)
166 return bbox
167
168 def SetProjection(self, projection):
169 """Set the projection of the map.
170
171 Issue a MAP_PROJECTION_CHANGED message."""
172 self.projection = projection
173 self.changed(MAP_PROJECTION_CHANGED, self)
174
175 def forward(self, *args):
176 """Reissue events"""
177 if len(args) > 1:
178 args = (args[-1],) + args[:-1]
179 apply(self.issue, args)
180
181 def WasModified(self):
182 """Return true if the map or one of the layers was modified"""
183 if self.modified:
184 return 1
185 else:
186 for layer in self.layers:
187 if layer.WasModified():
188 return 1
189 return self.label_layer.WasModified()
190
191 def UnsetModified(self):
192 """Unset the modified flag of the map and the layers"""
193 Modifiable.UnsetModified(self)
194 for layer in self.layers:
195 layer.UnsetModified()
196 self.label_layer.UnsetModified()
197
198 def TreeInfo(self):
199 items = []
200 if self.BoundingBox() != None:
201 items.append("Extent (lat-lon): (%g, %g, %g, %g)"
202 % self.BoundingBox())
203 if self.projection and len(self.projection.params) > 0:
204 items.append("Extent (projected): (%g, %g, %g, %g)"
205 % self.ProjectedBoundingBox())
206 items.append(("Projection",
207 [str(param)
208 for param in self.projection.params]))
209
210 layers = self.layers[:]
211 layers.reverse()
212 items.extend(layers)
213
214 return ("Map: %s" % self.title, items)
215

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26