/[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 1551 - (hide annotations)
Wed Aug 6 17:21:07 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: 7776 byte(s)
* Thuban/Model/data.py (ShapefileStore.Shape): For consistency, a
Shape object will always have the coordinates as a list of list of
coordinate pairs (tuples).
(Shape.compute_bbox): Adapt to new representation.

* Thuban/UI/viewport.py (ViewPort.find_shape_at)
(ViewPort.LabelShapeAt): Adapt to new coordinate representation in
Shape objects.

* test/test_shapefilestore.py
(ShapefileStoreTests.assertFloatTuplesEqual)
(ShapefileStoreTests.assertPointListEquals): Rename to
assertPointListEquals and change purpose to checking equality of
the lists returned by Shape.Points().
(TestShapefileStoreArc.test_shape)
(TestShapefileStorePolygon.test_shape)
(TestShapefileStorePoint.test_shape): Use the new
assertPointListEquals instead of assertFloatTuplesEqual

* test/test_layer.py (TestLayer.assertFloatTuplesEqual)
(TestLayer.assertPointListEquals): Rename to assertPointListEquals
and change purpose to checking equality of the lists returned by
Shape.Points().
(TestLayer.test_arc_layer, TestLayer.test_arc_layer)
(TestLayer.test_polygon_layer, TestLayer.test_point_layer)
(TestLayer.test_derived_store): Use the new assertPointListEquals
instead of assertFloatTuplesEqual

* test/test_derivedshapestore.py
(TestDerivedShapeStore.assertFloatTuplesEqual)
(TestDerivedShapeStore.assertPointListEquals): Rename to
assertPointListEquals and change purpose to checking equality of
the lists returned by Shape.Points().
(TestDerivedShapeStore.test_shape): Use the new
assertPointListEquals instead of assertFloatTuplesEqual

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