/[thuban]/trunk/thuban/Thuban/Model/layer.py
ViewVC logotype

Annotation of /trunk/thuban/Thuban/Model/layer.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 217 - (hide annotations)
Wed Jul 17 10:50:40 2002 UTC (22 years, 7 months ago) by bh
File MIME type: text/x-python
File size: 8514 byte(s)
* Thuban/UI/tree.py (color_string): Removed. No longer used.
(SessionTreeCtrl.update_tree, SessionTreeCtrl.add_items): Split
update_tree into update_tree and add_items. The tree now uses a
more generic way to display the contents of the tree.
(SessionTreeCtrl): Add a doc string explaining the TreeInfo method

* Thuban/Model/layer.py (Layer.TreeInfo),
Thuban/Model/extension.py (Extension.TreeInfo),
Thuban/Model/map.py (Map.TreeInfo),
Thuban/Model/session.py (Session.TreeInfo):
Add TreeInfo methods to implement the new tree view update scheme

1 bh 73 # 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 bh 171 from math import log, ceil
11    
12 bh 143 import shapelib, shptree
13 bh 6
14     from messages import LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \
15     LAYER_VISIBILITY_CHANGED
16    
17     from color import Color
18     # Some predefined colors for internal use
19     _black = Color(0, 0, 0)
20    
21    
22     from table import Table
23    
24     from base import TitledObject, Modifiable
25    
26     class Shape:
27    
28     """Represent one shape"""
29    
30     def __init__(self, points):
31     self.points = points
32     #self.compute_bbox()
33    
34     def compute_bbox(self):
35     xs = []
36     ys = []
37     for x, y in self.points:
38     xs.append(x)
39     ys.append(y)
40     self.llx = min(xs)
41     self.lly = min(ys)
42     self.urx = max(xs)
43     self.ury = max(ys)
44    
45     def Points(self):
46     return self.points
47    
48    
49    
50     # Shape type constants
51     SHAPETYPE_POLYGON = "polygon"
52     SHAPETYPE_ARC = "arc"
53     SHAPETYPE_POINT = "point"
54    
55     # mapping from shapelib shapetype constants to our constants
56     shapelib_shapetypes = {shapelib.SHPT_POLYGON: SHAPETYPE_POLYGON,
57     shapelib.SHPT_ARC: SHAPETYPE_ARC,
58     shapelib.SHPT_POINT: SHAPETYPE_POINT}
59    
60     shapetype_names = {SHAPETYPE_POINT: "Point",
61     SHAPETYPE_ARC: "Arc",
62     SHAPETYPE_POLYGON: "Polygon"}
63    
64     class BaseLayer(TitledObject, Modifiable):
65    
66     """Base class for the layers."""
67    
68     def __init__(self, title, visible = 1):
69     """Initialize the layer.
70    
71     title -- the title
72     visible -- boolean. If true the layer is visible.
73     """
74     TitledObject.__init__(self, title)
75     Modifiable.__init__(self)
76     self.visible = visible
77    
78     def Visible(self):
79     """Return true if layer is visible"""
80     return self.visible
81    
82     def SetVisible(self, visible):
83     """Set the layer's visibility."""
84     self.visible = visible
85     self.issue(LAYER_VISIBILITY_CHANGED, self)
86    
87    
88     class Layer(BaseLayer):
89    
90     """Represent the information of one geodata file (currently a shapefile)
91    
92     All children of the layer have the same type.
93    
94     A layer has fill and stroke colors. Colors should be instances of
95     Color. They can also be None, indicating no fill or no stroke.
96    
97     The layer objects send the following events, all of which have the
98     layer object as parameter:
99    
100     TITLE_CHANGED -- The title has changed.
101     LAYER_PROJECTION_CHANGED -- the projection has changed.
102     LAYER_LEGEND_CHANGED -- the fill or stroke attributes have changed
103    
104     """
105    
106     def __init__(self, title, filename, projection = None,
107 bh 73 fill = None, stroke = _black, stroke_width = 1, visible = 1):
108 bh 6 """Initialize the layer.
109    
110     title -- the title
111     filename -- the name of the shapefile
112     projection -- the projection object. Its Inverse method is
113     assumed to map the layer's coordinates to lat/long
114     coordinates
115     fill -- the fill color or None if the shapes are not filled
116     stroke -- the stroke color or None if the shapes are not stroked
117     visible -- boolean. If true the layer is visible.
118    
119     colors are expected to be instances of Color class
120     """
121     BaseLayer.__init__(self, title, visible = visible)
122     self.filename = filename
123     self.projection = projection
124     self.fill = fill
125     self.stroke = stroke
126 bh 73 self.stroke_width = stroke_width
127 bh 6 self.shapefile = None
128 bh 143 self.shapetree = None
129 bh 21 self.open_shapefile()
130 bh 6 # shapetable is the table associated with the shapefile, while
131     # table is the default table used to look up attributes for
132     # display
133     self.shapetable = Table(filename)
134     self.table = self.shapetable
135    
136     def open_shapefile(self):
137     if self.shapefile is None:
138     self.shapefile = shapelib.ShapeFile(self.filename)
139     numshapes, shapetype, mins, maxs = self.shapefile.info()
140     self.numshapes = numshapes
141     self.shapetype = shapelib_shapetypes[shapetype]
142    
143 bh 179 # if there are shapes, set the bbox accordinly. Otherwise
144     # set it to None.
145     if self.numshapes:
146     self.bbox = mins[:2] + maxs[:2]
147     else:
148     self.bbox = None
149    
150 bh 171 # estimate a good depth for the quad tree. Each depth
151     # multiplies the number of nodes by four, therefore we
152     # basically take the base 4 logarithm of the number of
153     # shapes.
154     if self.numshapes < 4:
155     maxdepth = 1
156     else:
157     maxdepth = int(ceil(log(self.numshapes / 4.0) / log(4)))
158    
159     self.shapetree = shptree.SHPTree(self.shapefile.cobject(), 2,
160     maxdepth)
161    
162 bh 6 def BoundingBox(self):
163 bh 179 """Return the layer's bounding box in the intrinsic coordinate system.
164    
165     If the layer has no shapes, return None.
166     """
167     # The bbox will be set by open_shapefile just as we need it
168     # here.
169 bh 6 self.open_shapefile()
170     return self.bbox
171    
172     def LatLongBoundingBox(self):
173 bh 179 """Return the layer's bounding box in lat/long coordinates.
174 bh 6
175 bh 179 Return None, if the layer doesn't contain any shapes.
176     """
177     bbox = self.BoundingBox()
178     if bbox is not None:
179     llx, lly, urx, ury = bbox
180     if self.projection is not None:
181     llx, lly = self.projection.Inverse(llx, lly)
182     urx, ury = self.projection.Inverse(urx, ury)
183     return llx, lly, urx, ury
184     else:
185     return None
186    
187 bh 6 def NumShapes(self):
188     """Return the number of shapes in the layer"""
189     self.open_shapefile()
190     return self.numshapes
191    
192     def ShapeType(self):
193     """Return the type of the shapes in the layer.
194     This is either SHAPETYPE_POINT, SHAPETYPE_ARC or SHAPETYPE_POLYGON.
195     """
196     self.open_shapefile()
197     return self.shapetype
198    
199     def Shape(self, index):
200     """Return the shape with index index"""
201     self.open_shapefile()
202     shape = self.shapefile.read_object(index)
203     if self.shapetype == SHAPETYPE_POINT:
204     points = shape.vertices()
205     else:
206     #for poly in shape.vertices():
207     poly = shape.vertices()[0]
208     points = []
209     for x, y in poly:
210 bh 82 points.append((x, y))
211 bh 6 return Shape(points)
212    
213 bh 143 def ShapesInRegion(self, box):
214     """Return the ids of the shapes that overlap the box.
215    
216     Box is a tuple (left, bottom, right, top) in the coordinate
217     system used by the layer's shapefile.
218     """
219     left, bottom, right, top = box
220 bh 147 return self.shapetree.find_shapes((left, bottom), (right, top))
221 bh 143
222 bh 6 def SetProjection(self, projection):
223     """Set the layer's projection"""
224     self.projection = projection
225     self.changed(LAYER_PROJECTION_CHANGED, self)
226    
227     def SetFill(self, fill):
228     """Set the layer's fill color. None means the shapes are not filled"""
229     self.fill = fill
230     self.changed(LAYER_LEGEND_CHANGED, self)
231    
232     def SetStroke(self, stroke):
233     """Set the layer's stroke color. None means the shapes are not
234     stroked."""
235     self.stroke = stroke
236     self.changed(LAYER_LEGEND_CHANGED, self)
237 bh 73
238     def SetStrokeWidth(self, width):
239     """Set the layer's stroke width."""
240     self.stroke_width = width
241     self.changed(LAYER_LEGEND_CHANGED, self)
242 bh 217
243     def TreeInfo(self):
244     items = []
245    
246     if self.Visible():
247     items.append("Shown")
248     else:
249     items.append("Hidden")
250     items.append("Shapes: %d" % self.NumShapes())
251    
252     bbox = self.LatLongBoundingBox()
253     if bbox is not None:
254     items.append("Extent (lat-lon): (%g, %g, %g, %g)" % bbox)
255     else:
256     items.append("Extent (lat-lon):")
257     items.append("Shapetype: %s" % shapetype_names[self.ShapeType()])
258    
259     def color_string(color):
260     if color is None:
261     return "None"
262     return "(%.3f, %.3f, %.3f)" % (color.red, color.green, color.blue)
263     items.append("Fill: " + color_string(self.fill))
264     items.append("Outline: " + color_string(self.stroke))
265    
266     return ("Layer '%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