/[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 171 - (hide annotations)
Tue May 14 14:16:24 2002 UTC (22 years, 9 months ago) by bh
File MIME type: text/x-python
File size: 7196 byte(s)
	* Thuban/Model/layer.py (Layer.open_shapefile): Choose a better
	maximum depth for the tree than shapelib does by default.

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     self.bbox = mins[:2] + maxs[:2]
143    
144 bh 171 # estimate a good depth for the quad tree. Each depth
145     # multiplies the number of nodes by four, therefore we
146     # basically take the base 4 logarithm of the number of
147     # shapes.
148     if self.numshapes < 4:
149     maxdepth = 1
150     else:
151     maxdepth = int(ceil(log(self.numshapes / 4.0) / log(4)))
152    
153     self.shapetree = shptree.SHPTree(self.shapefile.cobject(), 2,
154     maxdepth)
155    
156 bh 6 def BoundingBox(self):
157     """Return the bounding box of the layer's shapes in their default
158     coordinate system"""
159     self.open_shapefile()
160     return self.bbox
161    
162     def LatLongBoundingBox(self):
163     """Return the layer's bounding box in lat/long coordinates"""
164     llx, lly, urx, ury = self.BoundingBox()
165     if self.projection is not None:
166     llx, lly = self.projection.Inverse(llx, lly)
167     urx, ury = self.projection.Inverse(urx, ury)
168     return llx, lly, urx, ury
169    
170     def NumShapes(self):
171     """Return the number of shapes in the layer"""
172     self.open_shapefile()
173     return self.numshapes
174    
175     def ShapeType(self):
176     """Return the type of the shapes in the layer.
177     This is either SHAPETYPE_POINT, SHAPETYPE_ARC or SHAPETYPE_POLYGON.
178     """
179     self.open_shapefile()
180     return self.shapetype
181    
182     def Shape(self, index):
183     """Return the shape with index index"""
184     self.open_shapefile()
185     shape = self.shapefile.read_object(index)
186     if self.shapetype == SHAPETYPE_POINT:
187     points = shape.vertices()
188     else:
189     #for poly in shape.vertices():
190     poly = shape.vertices()[0]
191     points = []
192     for x, y in poly:
193 bh 82 points.append((x, y))
194 bh 6 return Shape(points)
195    
196 bh 143 def ShapesInRegion(self, box):
197     """Return the ids of the shapes that overlap the box.
198    
199     Box is a tuple (left, bottom, right, top) in the coordinate
200     system used by the layer's shapefile.
201     """
202     left, bottom, right, top = box
203 bh 147 return self.shapetree.find_shapes((left, bottom), (right, top))
204 bh 143
205 bh 6 def SetProjection(self, projection):
206     """Set the layer's projection"""
207     self.projection = projection
208     self.changed(LAYER_PROJECTION_CHANGED, self)
209    
210     def SetFill(self, fill):
211     """Set the layer's fill color. None means the shapes are not filled"""
212     self.fill = fill
213     self.changed(LAYER_LEGEND_CHANGED, self)
214    
215     def SetStroke(self, stroke):
216     """Set the layer's stroke color. None means the shapes are not
217     stroked."""
218     self.stroke = stroke
219     self.changed(LAYER_LEGEND_CHANGED, self)
220 bh 73
221     def SetStrokeWidth(self, width):
222     """Set the layer's stroke width."""
223     self.stroke_width = width
224     self.changed(LAYER_LEGEND_CHANGED, self)

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26