/[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 765 by bh, Tue Apr 29 12:42:14 2003 UTC revision 1593 by bh, Fri Aug 15 14:10:27 2003 UTC
# Line 7  Line 7 
7    
8  """Data source abstractions"""  """Data source abstractions"""
9    
10    from __future__ import generators
11    
12  __version__ = "$Revision$"  __version__ = "$Revision$"
13  # $Source$  # $Source$
14  # $Id$  # $Id$
15    
16  import os  import os
17    import weakref
18    from math import ceil, log
19    
20  import shapelib  import shapelib
21    import shptree
22  import table  import table
23  import transientdb  import transientdb
24    
25    from Thuban import _
26    
27    # Shape type constants
28    SHAPETYPE_POLYGON = "polygon"
29    SHAPETYPE_ARC = "arc"
30    SHAPETYPE_POINT = "point"
31    
32    # 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    #
38    # Raw shape data formats
39    #
40    
41    # Raw data is the same as that returned by the points method.
42    RAW_PYTHON = "RAW_PYTHON"
43    
44    # Raw data is a shapefile. The Shape object will use the shapeid as the
45    # raw data.
46    RAW_SHAPEFILE = "RAW_SHAPEFILE"
47    
48    
49    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        def compute_bbox(self):
58            """
59            Return the bounding box of the shape as a tuple (minx,miny,maxx,maxy)
60            """
61            xs = []
62            ys = []
63            for part in self.Points():
64                for x, y in part:
65                    xs.append(x)
66                    ys.append(y)
67            return (min(xs), min(ys), max(xs), max(ys))
68    
69        def ShapeID(self):
70            return self.shapeid
71    
72        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    
80        def RawData(self):
81            """Return the shape id to use with the shapefile"""
82            return self.shapeid
83    
84        def Shapefile(self):
85            """Return the shapefile object"""
86            return self.shapefile
87    
88    
89    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  class ShapefileStore:  class ShapefileStore:
114    
# Line 31  class ShapefileStore: Line 123  class ShapefileStore:
123    
124          self.shapefile = shapelib.ShapeFile(self.filename)          self.shapefile = shapelib.ShapeFile(self.filename)
125          self.dbftable = table.DBFTable(filename)          self.dbftable = table.DBFTable(filename)
126          self.table = transientdb.AutoTransientTable(session.TransientDB(),          self.table = ShapeTable(self, session.TransientDB(), self.dbftable)
127                                                      self.dbftable)  
128            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      def Table(self):      def Table(self):
147            """Return the table containing the attribute data"""
148          return self.table          return self.table
149    
150      def Shapefile(self):      def Shapefile(self):
151            """Return the shapefile object"""
152          return self.shapefile          return self.shapefile
153    
154        def FileName(self):
155            """Return the filename used to open the shapefile"""
156            return self.filename
157    
158  class SimpleStore:      def FileType(self):
159            """Return the filetype. This is always the string 'shapefile'"""
160            return "shapefile"
161    
162      """Combine a shapefile and a table object"""      def ShapeType(self):
163            """Return the type of the shapes in the shapestore.
164    
165      def __init__(self, shapefile, table):          This is either SHAPETYPE_POINT, SHAPETYPE_ARC or SHAPETYPE_POLYGON.
166          self.shapefile = shapefile          """
167            return self.shapetype
168    
169        def RawShapeFormat(self):
170            """Return the raw data format of the shape data, i.e. RAW_SHAPEFILE"""
171            return RAW_SHAPEFILE
172    
173        def NumShapes(self):
174            """Return the number of shapes in the shape store"""
175            return self.numshapes
176    
177        def Dependencies(self):
178            """Return the empty tuple.
179    
180            The ShapefileStore doesn't depend on anything else.
181            """
182            return ()
183    
184        def OrigShapeStore(self):
185            """Return None.
186    
187            The ShapefileStore was not derived from another shapestore.
188            """
189            return None
190    
191        def BoundingBox(self):
192            """Return the bounding box of the shapes in the shapestore.
193    
194            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        def ShapesInRegion(self, bbox):
200            """Return an iterable over the shapes that overlap the bounding box.
201    
202            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            """
206            left, bottom, right, top = bbox
207            for i in self.shapetree.find_shapes((left, bottom), (right, top)):
208                yield ShapefileShape(self.shapefile, i)
209    
210        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        def Shape(self, index):
216            """Return the shape with index index"""
217            return ShapefileShape(self.shapefile, index)
218    
219    
220    
221    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    
231            Raises ValueError if the number of shapes in the shapestore
232            is different from the number of rows in the table.
233            """
234    
235            numShapes = shapestore.Shapefile().info()[0]
236            if numShapes != table.NumRows():
237                raise ValueError(_("Table not compatible with shapestore."))
238    
239            self.shapestore = shapestore
240          self.table = table          self.table = table
         self.filename = None  
241    
242      def Table(self):      def Table(self):
243            """Return the table"""
244          return self.table          return self.table
245    
246      def Shapefile(self):      def Shapefile(self):
247          return self.shapefile          """Return the shapefile of the underlying shapestore"""
248            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        def OrigShapeStore(self):
255            """
256            Return the original shapestore the derived store was instantiated with
257            """
258            return self.shapestore
259    
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        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        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        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        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()

Legend:
Removed from v.765  
changed lines
  Added in v.1593

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26