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

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

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

revision 1638 by bh, Fri Aug 22 18:19:14 2003 UTC revision 1693 by bh, Mon Sep 1 11:23:26 2003 UTC
# Line 129  class PostGISColumn: Line 129  class PostGISColumn:
129    
130  class PostGISTable:  class PostGISTable:
131    
132      """A Table in a PostGIS database"""      """A Table in a PostGIS database
133    
134        A PostgreSQL table may contain columns with types not (yet)
135        supported by Thuban. Instances of this class ignore those columns
136        and pretend they don't exist, i.e. they won't show up in the column
137        descriptions returned by Columns() and other methods.
138        """
139    
140      def __init__(self, db, tablename):      def __init__(self, db, tablename):
141          """Initialize the PostGISTable.          """Initialize the PostGISTable.
# Line 152  class PostGISTable: Line 158  class PostGISTable:
158          for i in range(len(description)):          for i in range(len(description)):
159              for pgtyp, tabletyp in type_map:              for pgtyp, tabletyp in type_map:
160                  if pgtyp == description[i][1]:                  if pgtyp == description[i][1]:
161                      col = PostGISColumn(description[i][0], tabletyp, i)                      col = PostGISColumn(description[i][0], tabletyp,
162                                            len(self.columns))
163                      break                      break
164              else:              else:
165                  if description[i][1] == self.db.geometry_type:                  if description[i][1] == self.db.geometry_type:
# Line 180  class PostGISTable: Line 187  class PostGISTable:
187          """Return the name of the table in the database"""          """Return the name of the table in the database"""
188          return self.tablename          return self.tablename
189    
190        def Title(self):
191            """Return the title of the table.
192    
193            The title is currently fixed and equal to the tablename
194            """
195            return self.tablename
196    
197      def Dependencies(self):      def Dependencies(self):
198          """Return an empty tuple because a PostGISTable depends on nothing else          """Return an empty tuple because a PostGISTable depends on nothing else
199          """          """
# Line 202  class PostGISTable: Line 216  class PostGISTable:
216          cursor.execute("SELECT count(*) FROM %s" % self.tablename)          cursor.execute("SELECT count(*) FROM %s" % self.tablename)
217          return cursor.fetchone()[0]          return cursor.fetchone()[0]
218    
219      def ReadRowAsDict(self, row):      def RowIdToOrdinal(self, gid):
220            """Return the row ordinal given its id"""
221            cursor = self.db.cursor()
222            cursor.execute("SELECT count(*) FROM %s WHERE gid < %d;"
223                           % (self.tablename, gid))
224            return cursor.fetchone()[0]
225    
226        def RowOrdinalToId(self, num):
227            """Return the rowid for given its ordinal"""
228            cursor = self.db.cursor()
229            cursor.execute("SELECT gid FROM %s LIMIT 1 OFFSET %d;"
230                           % (self.tablename, num))
231            return cursor.fetchone()[0]
232    
233        def ReadRowAsDict(self, row, row_is_ordinal = 0):
234          cursor = self.db.cursor()          cursor = self.db.cursor()
235          cursor.execute(self.query_stmt + " LIMIT 1 OFFSET %d" % row)          if row_is_ordinal:
236                stmt = self.query_stmt + " LIMIT 1 OFFSET %d" % row
237            else:
238                stmt = self.query_stmt + " WHERE gid = %d" % row
239            cursor.execute(stmt)
240          result = {}          result = {}
241          for col, value in zip(self.columns, cursor.fetchone()):          for col, value in zip(self.columns, cursor.fetchone()):
242              result[col.name] = value              result[col.name] = value
243          return result          return result
244    
245      def ReadValue(self, row, col):      def ReadValue(self, row, col, row_is_ordinal = 0):
246          cursor = self.db.cursor()          cursor = self.db.cursor()
247          cursor.execute("SELECT %s FROM %s LIMIT 1 OFFSET %d" %          if row_is_ordinal:
248                         (self.column_map[col].name, self.tablename, row))              stmt = ("SELECT %s FROM %s LIMIT 1 OFFSET %d" %
249                        (self.column_map[col].name, self.tablename, row))
250            else:
251                stmt = ("SELECT %s FROM %s WHERE gid = %d" %
252                        (self.column_map[col].name, self.tablename, row))
253            cursor.execute(stmt)
254          return cursor.fetchone()[0]          return cursor.fetchone()[0]
255    
256      def ValueRange(self, col):      def ValueRange(self, col):
# Line 287  class PostGISShape: Line 324  class PostGISShape:
324    
325    
326  shapetype_map = {"POLYGON": SHAPETYPE_POLYGON,  shapetype_map = {"POLYGON": SHAPETYPE_POLYGON,
327                     "MULTIPOLYGON": SHAPETYPE_POLYGON,
328                   "MULTILINESTRING": SHAPETYPE_ARC,                   "MULTILINESTRING": SHAPETYPE_ARC,
329                   "POINT": SHAPETYPE_POINT}                   "POINT": SHAPETYPE_POINT}
330    
# Line 332  class PostGISShapeStore(PostGISTable): Line 370  class PostGISShapeStore(PostGISTable):
370          y=[]          y=[]
371          cursor = self.db.cursor()          cursor = self.db.cursor()
372          try:          try:
373              stmt = ("SELECT AsText(Envelope(%s)) FROM %s;"              # Using the extent function is postgis specific. An OGC
374                      % (self.geometry_column, self.tablename))              # Simple Features compliant solution would be to use a query
375              cursor.execute(stmt)              # like "SELECT AsText(Envelope(the_geom)) FROM mytable;" and
376                # calculate the bounding box by hand from that
377                cursor.execute("SELECT extent(%s) FROM %s;"
378                               % (self.geometry_column, self.tablename))
379              result = cursor.fetchone()              result = cursor.fetchone()
380              while result:              if result:
381                  result = result[0]                  (minx, miny), (maxx, maxy) \
382                  # Here we must do some parsing through the result string                        = wellknowntext.parse_wkt_thuban(result[0])[0]
383                  # to get the points out of the polygon which representes                  return (minx, miny, maxx, maxy)
                 # the bounding box The first and the last point of a  
                 # polygon are identical  
                 result = result.split("(")[2]  
                 result = result.split(")")[0]  
                 points = result.split(",")  
                 del points[4] # Remove the last point  
                 for point in points:  
                     px, py = point.split()  
                     x.append(float(px))  
                     y.append(float(py))  
                 result = cursor.fetchone()  
384          finally:          finally:
385              cursor.close()              cursor.close()
         if not x:  
             # Empty table  
             return None  
         return (min(x), min(y), max(x), max(y))  
386    
387      def Shape(self, shapeid):      def Shape(self, shapeid):
388          cursor = self.db.cursor()          cursor = self.db.cursor()
# Line 366  class PostGISShapeStore(PostGISTable): Line 392  class PostGISShapeStore(PostGISTable):
392          cursor.close()          cursor.close()
393          return PostGISShape(shapeid, wkt)          return PostGISShape(shapeid, wkt)
394    
395        def AllShapes(self):
396            cursor = self.db.cursor()
397            cursor.execute("SELECT gid, AsText(%s) FROM %s ORDER BY gid"
398                           % (self.geometry_column, self.tablename))
399            while 1:
400                result = cursor.fetchone()
401                if result is None:
402                    return
403                yield PostGISShape(result[0], result[1])
404    
405    
406      def ShapesInRegion(self, bbox):      def ShapesInRegion(self, bbox):
407          """Generate all shapes overlapping the region given by bbox."""          """Generate all shapes overlapping the region given by bbox."""
408          # IMPORTANT:This will work for PostGIS < 0.8          # IMPORTANT:This will work for PostGIS < 0.8
# Line 381  class PostGISShapeStore(PostGISTable): Line 418  class PostGISShapeStore(PostGISTable):
418          while 1:          while 1:
419              result = cursor.fetchone()              result = cursor.fetchone()
420              if result is None:              if result is None:
421                  raise StopIteration                  return
422              yield PostGISShape(result[0], result[1])              yield PostGISShape(result[0], result[1])

Legend:
Removed from v.1638  
changed lines
  Added in v.1693

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26