/[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 707 - (show annotations)
Wed Apr 23 08:44:34 2003 UTC (21 years, 10 months ago) by jonathan
Original Path: trunk/thuban/Thuban/Model/map.py
File MIME type: text/x-python
File size: 8053 byte(s)
(Map.GetProjection): New. Returns the map's projection.

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

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26