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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 723 by bh, Thu Apr 24 15:31:53 2003 UTC revision 1551 by bh, Wed Aug 6 17:21:07 2003 UTC
# Line 12  __version__ = "$Revision$" Line 12  __version__ = "$Revision$"
12  # $Id$  # $Id$
13    
14  import os  import os
15    import weakref
16    from math import ceil, log
17    
18  import shapelib  import shapelib
19    import shptree
20  import table  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    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            for part in self.points:
52                for x, y in part:
53                    xs.append(x)
54                    ys.append(y)
55            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    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  class ShapefileStore:  class ShapefileStore:
94    
# Line 28  class ShapefileStore: Line 102  class ShapefileStore:
102          self.filename = os.path.abspath(filename)          self.filename = os.path.abspath(filename)
103    
104          self.shapefile = shapelib.ShapeFile(self.filename)          self.shapefile = shapelib.ShapeFile(self.filename)
105          self.table = table.Table(filename)          self.dbftable = table.DBFTable(filename)
106            self.table = ShapeTable(self, session.TransientDB(), self.dbftable)
107    
108            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      def Table(self):      def Table(self):
127            """Return the table containing the attribute data"""
128          return self.table          return self.table
129    
130      def Shapefile(self):      def Shapefile(self):
131            """Return the shapefile object"""
132          return self.shapefile          return self.shapefile
133    
134        def FileName(self):
135            """Return the filename used to open the shapefile"""
136            return self.filename
137    
138        def FileType(self):
139            """Return the filetype. This is always the string 'shapefile'"""
140            return "shapefile"
141    
142        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        def Dependencies(self):
154            """Return the empty tuple.
155    
156            The ShapefileStore doesn't depend on anything else.
157            """
158            return ()
159    
160        def OrigShapeStore(self):
161            """Return None.
162    
163            The ShapefileStore was not derived from another shapestore.
164            """
165            return None
166    
167        def BoundingBox(self):
168            """Return the bounding box of the shapes in the shapestore.
169    
170            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                points = [shape.vertices()]
190            else:
191                points = []
192                for poly in shape.vertices():
193                    part = []
194                    for x, y in poly:
195                        part.append((x, y))
196                    points.append(part)
197    
198            return Shape(points)
199    
200    
201    
202    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    
212            Raises ValueError if the number of shapes in the shapestore
213            is different from the number of rows in the table.
214            """
215    
216            numShapes = shapestore.Shapefile().info()[0]
217            if numShapes != table.NumRows():
218                raise ValueError(_("Table not compatible with shapestore."))
219    
220            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            """Return the shapefile of the underlying shapestore"""
229            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        def OrigShapeStore(self):
236            """
237            Return the original shapestore the derived store was instantiated with
238            """
239            return self.shapestore
240    
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()

Legend:
Removed from v.723  
changed lines
  Added in v.1551

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26