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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1593 - (hide annotations)
Fri Aug 15 14:10:27 2003 UTC (21 years, 6 months ago) by bh
Original Path: trunk/thuban/Thuban/Model/data.py
File MIME type: text/x-python
File size: 9113 byte(s)
Change the way shapes are returned by a shape store. The
ShapesInRegion method returns an iterator over actual shape
objects instead of a list of shape ids.

* Thuban/Model/data.py (ShapefileShape.ShapeID): New. Return shape
id.
(ShapefileStore.ShapesInRegion): Return an iterator over the
shapes which yields shape objects instead of returning a list of
shape ids
(ShapefileStore.AllShapes): New. Return an iterator over all
shapes in the shape store
(DerivedShapeStore.AllShapes): New. Like in ShapefileStore

* Thuban/Model/layer.py (Layer.ShapesInRegion): Update
doc-string.

* Thuban/UI/baserenderer.py
(BaseRenderer.layer_ids, BaseRenderer.layer_shapes): Rename to
layer_shapes and make it return an iterator containg shapes
instead of a list of ids.
(BaseRenderer.draw_shape_layer): Update doc-string; Adapt to
layer_shapes() change

* Thuban/UI/renderer.py (ScreenRenderer.layer_ids)
(ScreenRenderer.layer_shapes): Rename as in BaseRenderer

* Thuban/UI/viewport.py (ViewPort._find_shape_in_layer): Adapt to
changes in the ShapesInRegion return value.
(ViewPort._get_hit_tester): Remove commented out code

* test/mockgeo.py (SimpleShapeStore.ShapesInRegion): Adapt to the
new return value.
(SimpleShapeStore.AllShapes): New. Implement this method too.

* test/test_layer.py (TestLayer.test_arc_layer)
(TestLayer.test_polygon_layer, TestLayer.test_point_layer)
(TestLayer.test_point_layer_with_projection)
(TestLayer.test_derived_store): Adapt to changes in the
ShapesInRegion return value.

* test/test_shapefilestore.py
(TestShapefileStoreArc.test_shapes_in_region)
(TestShapefileStorePolygon.test_shapes_in_region)
(TestShapefileStorePoint.test_shapes_in_region): Adapt to changes
in the ShapesInRegion return value.
(TestShapefileStorePoint.test_all_shapes)
(TestShapefileStoreArc.test_shape_shapeid): New tests for the new
methods

* test/test_derivedshapestore.py
(TestDerivedShapeStore.test_shapes_in_region): Adapt to changes in
the ShapesInRegion return value.
(TestDerivedShapeStore.test_all_shapes)
(TestDerivedShapeStore.test_shape_shapeid): New tests for the new
methods

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