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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1559 - (show annotations)
Thu Aug 7 17:32:20 2003 UTC (21 years, 7 months ago) by bh
Original Path: trunk/thuban/Thuban/Model/data.py
File MIME type: text/x-python
File size: 8197 byte(s)
update ChangeLog

1 # Copyright (C) 2003 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 the software for details.
7
8 """Data source abstractions"""
9
10 __version__ = "$Revision$"
11 # $Source$
12 # $Id$
13
14 import os
15 import weakref
16 from math import ceil, log
17
18 import shapelib
19 import shptree
20 import table
21 import transientdb
22
23 from Thuban import _
24
25 # Shape type constants
26 SHAPETYPE_POLYGON = "polygon"
27 SHAPETYPE_ARC = "arc"
28 SHAPETYPE_POINT = "point"
29
30 # mapping from shapelib shapetype constants to our constants
31 shapelib_shapetypes = {shapelib.SHPT_POLYGON: SHAPETYPE_POLYGON,
32 shapelib.SHPT_ARC: SHAPETYPE_ARC,
33 shapelib.SHPT_POINT: SHAPETYPE_POINT}
34
35 #
36 # Raw shape data formats
37 #
38
39 # Raw data is the same as that returned by the points method.
40 RAW_PYTHON = "RAW_PYTHON"
41
42 # Raw data is a shapefile. The Shape object will use the shapeid as the
43 # raw data.
44 RAW_SHAPEFILE = "RAW_SHAPEFILE"
45
46
47 class ShapefileShape:
48
49 """Represent one shape of a shapefile"""
50
51 def __init__(self, shapefile, shapeid):
52 self.shapefile = shapefile
53 self.shapeid = shapeid
54
55 def compute_bbox(self):
56 """
57 Return the bounding box of the shape as a tuple (minx,miny,maxx,maxy)
58 """
59 xs = []
60 ys = []
61 for part in self.Points():
62 for x, y in part:
63 xs.append(x)
64 ys.append(y)
65 return (min(xs), min(ys), max(xs), max(ys))
66
67 def Points(self):
68 """Return the coordinates of the shape as a list of lists of pairs"""
69 shape = self.shapefile.read_object(self.shapeid)
70 points = shape.vertices()
71 if self.shapefile.info()[1] == shapelib.SHPT_POINT:
72 points = [points]
73 return points
74
75 def RawData(self):
76 """Return the shape id to use with the shapefile"""
77 return self.shapeid
78
79 def Shapefile(self):
80 """Return the shapefile object"""
81 return self.shapefile
82
83
84 class ShapeTable(transientdb.AutoTransientTable):
85
86 """A Table that depends on a ShapefileStore
87
88 Intended use is by the ShapefileStore for the table associated with
89 the shapefiles.
90 """
91
92 def __init__(self, store, db, table):
93 """Initialize the ShapeTable.
94
95 Parameters:
96 store -- the ShapefileStore the table is to depend on
97 db -- The transient database to use
98 table -- the table
99 """
100 transientdb.AutoTransientTable.__init__(self, db, table)
101 self.store = weakref.ref(store)
102
103 def Dependencies(self):
104 """Return a tuple containing the shapestore"""
105 return (self.store(),)
106
107
108 class ShapefileStore:
109
110 """Combine a shapefile and the corresponding DBF file into one object"""
111
112 def __init__(self, session, filename):
113 # Make the filename absolute. The filename will be
114 # interpreted relative to that anyway, but when saving a
115 # session we need to compare absolute paths and it's usually
116 # safer to always work with absolute paths.
117 self.filename = os.path.abspath(filename)
118
119 self.shapefile = shapelib.ShapeFile(self.filename)
120 self.dbftable = table.DBFTable(filename)
121 self.table = ShapeTable(self, session.TransientDB(), self.dbftable)
122
123 self.numshapes, shapetype, mins, maxs = self.shapefile.info()
124 if self.numshapes:
125 self.bbox = mins[:2] + maxs[:2]
126 else:
127 self.bbox = None
128 self.shapetype = shapelib_shapetypes[shapetype]
129
130 # estimate a good depth for the quad tree. Each depth multiplies
131 # the number of nodes by four, therefore we basically take the
132 # base 4 logarithm of the number of shapes.
133 if self.numshapes < 4:
134 maxdepth = 1
135 else:
136 maxdepth = int(ceil(log(self.numshapes / 4.0) / log(4)))
137
138 self.shapetree = shptree.SHPTree(self.shapefile.cobject(), 2,
139 maxdepth)
140
141 def Table(self):
142 """Return the table containing the attribute data"""
143 return self.table
144
145 def Shapefile(self):
146 """Return the shapefile object"""
147 return self.shapefile
148
149 def FileName(self):
150 """Return the filename used to open the shapefile"""
151 return self.filename
152
153 def FileType(self):
154 """Return the filetype. This is always the string 'shapefile'"""
155 return "shapefile"
156
157 def ShapeType(self):
158 """Return the type of the shapes in the shapestore.
159
160 This is either SHAPETYPE_POINT, SHAPETYPE_ARC or SHAPETYPE_POLYGON.
161 """
162 return self.shapetype
163
164 def RawShapeFormat(self):
165 """Return the raw data format of the shape data, i.e. RAW_SHAPEFILE"""
166 return RAW_SHAPEFILE
167
168 def NumShapes(self):
169 """Return the number of shapes in the shape store"""
170 return self.numshapes
171
172 def Dependencies(self):
173 """Return the empty tuple.
174
175 The ShapefileStore doesn't depend on anything else.
176 """
177 return ()
178
179 def OrigShapeStore(self):
180 """Return None.
181
182 The ShapefileStore was not derived from another shapestore.
183 """
184 return None
185
186 def BoundingBox(self):
187 """Return the bounding box of the shapes in the shapestore.
188
189 The coordinate system used is whatever was used in the shapefile.
190 If the shapefile is empty, return None.
191 """
192 return self.bbox
193
194 def ShapesInRegion(self, box):
195 """Return the ids of the shapes that overlap the box.
196
197 Box is a tuple (left, bottom, right, top) in the coordinate
198 system used used in the shapefile.
199 """
200 left, bottom, right, top = box
201 return self.shapetree.find_shapes((left, bottom), (right, top))
202
203 def Shape(self, index):
204 """Return the shape with index index"""
205 return ShapefileShape(self.shapefile, index)
206
207
208
209 class DerivedShapeStore:
210
211 """A ShapeStore derived from other shapestores or tables"""
212
213 def __init__(self, shapestore, table):
214 """Initialize the derived shapestore.
215
216 The arguments are a shapestore for the shapedata and a table for
217 the tabular data.
218
219 Raises ValueError if the number of shapes in the shapestore
220 is different from the number of rows in the table.
221 """
222
223 numShapes = shapestore.Shapefile().info()[0]
224 if numShapes != table.NumRows():
225 raise ValueError(_("Table not compatible with shapestore."))
226
227 self.shapestore = shapestore
228 self.table = table
229
230 def Table(self):
231 """Return the table"""
232 return self.table
233
234 def Shapefile(self):
235 """Return the shapefile of the underlying shapestore"""
236 return self.shapestore.Shapefile()
237
238 def Dependencies(self):
239 """Return a tuple containing the shapestore and the table"""
240 return (self.shapestore, self.table)
241
242 def OrigShapeStore(self):
243 """
244 Return the original shapestore the derived store was instantiated with
245 """
246 return self.shapestore
247
248 def Shape(self, index):
249 """Return the shape with index index"""
250 return self.shapestore.Shape(index)
251
252 def ShapesInRegion(self, bbox):
253 """Return the ids of the shapes that overlap the box.
254
255 This method is simply delegated to the shapestore the
256 DerivedShapeStore was instantiated with.
257 """
258 return self.shapestore.ShapesInRegion(bbox)
259
260 def ShapeType(self):
261 """Return the type of the shapes in the layer.
262
263 This method is simply delegated to the shapestore the
264 DerivedShapeStore was instantiated with.
265 """
266 return self.shapestore.ShapeType()
267
268 def NumShapes(self):
269 """Return the number of shapes in the shapestore."""
270 return self.shapestore.NumShapes()
271
272 def BoundingBox(self):
273 """Return the bounding box of the shapes in the shapestore.
274
275 This method is simply delegated to the shapestore the
276 DerivedShapeStore was instantiated with.
277 """
278 return self.shapestore.BoundingBox()

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26