/[thuban]/branches/WIP-pyshapelib-bramz/Extensions/ogr/ogrshapes.py
ViewVC logotype

Diff of /branches/WIP-pyshapelib-bramz/Extensions/ogr/ogrshapes.py

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

revision 2559 by nhueffme, Tue Feb 8 09:52:56 2005 UTC revision 2577 by nhueffme, Fri Mar 4 15:07:59 2005 UTC
# Line 17  except ImportError: Line 17  except ImportError:
17      ogr = None      ogr = None
18    
19  import os  import os
 import weakref  
 from math import ceil, log  
20    
21  from Thuban import _  from Thuban import _
22  from Thuban.Model import table  from Thuban.Model import table
23    from Thuban.Model import transientdb
24    from Thuban.Model.transientdb import  TransientDatabase
25    
26  from Thuban.Model.data import SHAPETYPE_POLYGON, SHAPETYPE_ARC, SHAPETYPE_POINT  from Thuban.Model.data import SHAPETYPE_POLYGON, SHAPETYPE_ARC, SHAPETYPE_POINT
27  from Thuban.Model.data import RAW_PYTHON, RAW_SHAPEFILE, RAW_WKT  from Thuban.Model.data import RAW_PYTHON, RAW_SHAPEFILE, RAW_WKT
28    
 SHAPETYPE_UNKNOWN = ogr.wkbUnknown  
   
29  def has_ogr_support():  def has_ogr_support():
30      """Return whether this Thuban instance supports ogr file formats      """Return whether this Thuban instance supports ogr file formats
31    
# Line 37  def has_ogr_support(): Line 35  def has_ogr_support():
35      return ogr is not None      return ogr is not None
36    
37  if ogr is not None:  if ogr is not None:
38      # mapping from ogr-lib shapetype and table constants to our constants      SHAPETYPE_UNKNOWN = ogr.wkbUnknown
39        SHAPETYPE_GEOMCOLL = ogr.wkbGeometryCollection
40        SHAPETYPE_NONE = ogr.wkbNone
41    
42        # mapping from ogr-lib shapetypes and table constants to our constants
43      ogrlib_shapetypes = {ogr.wkbPolygon: SHAPETYPE_POLYGON,      ogrlib_shapetypes = {ogr.wkbPolygon: SHAPETYPE_POLYGON,
44                  ogr.wkbLineString: SHAPETYPE_ARC,                  ogr.wkbLineString: SHAPETYPE_ARC,
45                  ogr.wkbPoint: SHAPETYPE_POINT,                  ogr.wkbPoint: SHAPETYPE_POINT,
46                  ogr.wkbUnknown: SHAPETYPE_UNKNOWN}                  ogr.wkbUnknown: SHAPETYPE_UNKNOWN,
47                    ogr.wkbNone: SHAPETYPE_NONE,
48                    ogr.wkbGeometryCollection: SHAPETYPE_GEOMCOLL}
49    
50      fieldtype_map = {ogr.OFTString: table.FIELDTYPE_STRING,      fieldtype_map = {ogr.OFTString: table.FIELDTYPE_STRING,
51                  ogr.OFTInteger: table.FIELDTYPE_INT,                  ogr.OFTInteger: table.FIELDTYPE_INT,
52                  ogr.OFTReal: table.FIELDTYPE_DOUBLE}                  ogr.OFTReal: table.FIELDTYPE_DOUBLE}
53    
54    else:
55        ogrlib_shapetypes = {}
56        fieldtype_map = {}
57        SHAPETYPE_UNKNOWN = 0
58        SHAPETYPE_GEOMCOLL = 7
59        SHAPETYPE_NONE = 100
60    
61    
62  class OGRShape:  class OGRShape:
63        """Represent one shape of an OGRShapeStore
64        """
65    
66      """Represent one shape of an OGRShapeStore"""      def __init__(self, shapestore, shape):
67            """Initialize the shape object.
68    
69      def __init__(self, ogrlayer, shapeid):          shapestore should be an instance of OGRShapeStore,
70          self.ogrlayer = ogrlayer          shape should be an instance of an OGRFeature.
71          self.feature = self.ogrlayer.GetFeature(shapeid)          """
72          self.shapeid = shapeid          self.ogrlayer = shapestore.ogrlayer
73            id_column = shapestore.Id_column()
74            self.feature = shape
75            if id_column is None:
76                self.shapeid = self.feature.GetFID()
77            else:
78                self.shapeid = self.feature.GetField(id_column)
79          self.geom = self.feature.GetGeometryRef()          self.geom = self.feature.GetGeometryRef()
80          self.shapetype = self.geom.GetGeometryType()          if self.geom:
81                self.shapetype = self.geom.GetGeometryType()
82                self.bbox = self._compute_bbox()
83                self.points = self._points()
84            else:
85                self.shapetype = ogr.wkbNone
86                self.bbox = None
87                self.points = [[]]
88            try:
89                self.shapetype = ogrlib_shapetypes[self.shapetype]
90            except:
91                self.shapetype = ogrlib_shapetypes[ogr.wkbUnknown]
92    
93      def compute_bbox(self):          self.geoms = self._geoms()
94    
95        def _geoms(self):
96            """Return a list of geometry objects.
97    
98            If the shape is a geometry collection, all contained geometry
99            objects are stored to the list as OGRGeometry objects.
100          """          """
101          Return the bounding box of the shape as a tuple (minx,miny,maxx,maxy)          geoms = []
102            if self.shapetype == SHAPETYPE_GEOMCOLL:
103                for i in range(self.geom.GetGeometryCount()):
104                    geoms.append(OGRGeometry(self, self.geom, i))
105            return geoms
106    
107        def _compute_bbox(self):
108            """
109            Compute the bounding box of the shape as a tuple (minx,miny,maxx,maxy)
110          """          """
111          minx, maxx, miny, maxy = self.geom.GetEnvelope()          minx, maxx, miny, maxy = self.geom.GetEnvelope()
112          return (minx, miny, maxx, maxy)          return (minx, miny, maxx, maxy)
113    
114        def compute_bbox(self):
115            """
116            Return the bounding box of the shape as a tuple (minx,miny,maxx,maxy)
117            """
118            return self.bbox
119    
120      def ShapeID(self):      def ShapeID(self):
121            """Return the feature id of this shape.
122            """
123          return self.shapeid          return self.shapeid
124    
125      def Points(self):      def Points(self):
126          """Return the coordinates of the shape as a list of lists of pairs"""          """Return the coordinates of the shape as a list of lists of pairs
127          shape = []          """
128          #spatialFilter = self.ogrlayer.GetSpatialFilter()          return self.points
129    
130          #if spatialFilter is not None:      def _points(self):
131          #self.ogrlayer.SetSpatialFilter(None)          """Get the coordinates of the shape as a list of lists of pairs
132              #feature = self.ogrlayer.GetFeature(self.shapeid)          """
133              #self.ogrlayer.SetSpatialFilter(spatialFilter)          shape = []
         #else:  
         #feature = self.ogrlayer.GetFeature(self.shapeid)  
   
         #if feature is None:  
          #   return shape.append([])  
         #geom = feature.GetGeometryRef()  
134    
135          if self.geom is None:          if self.geom is None:
136              return shape.append([])              return shape.append([])
# Line 107  class OGRShape: Line 154  class OGRShape:
154                      y = geometry.GetY(point)                      y = geometry.GetY(point)
155                      points.append((x, y))                      points.append((x, y))
156                  shape.append(points)                  shape.append(points)
157              # if geometry object is of type multipolygon              # if geometry object is of type multipolygon or geometry collection
158              else:              else:
159                  for j in range(geometry.GetGeometryCount()):                  for j in range(geometry.GetGeometryCount()):
160                      points = []                      points = []
# Line 120  class OGRShape: Line 167  class OGRShape:
167          return shape          return shape
168    
169      def RawData(self):      def RawData(self):
170          """Return the shape id to use with the shapestore"""          """Return the shape id to use with the shapestore
171            """
172          return self.shapeid          return self.shapeid
173    
174      def OGRLayer(self):      def OGRLayer(self):
175          """Return the ogrlayer object"""          """Return the ogrlayer object
176            """
177          return self.ogrlayer          return self.ogrlayer
178    
179      def ShapeType(self):      def ShapeType(self):
180            """Return the shapetype of this shape (may differ from the layer's
181            shapetype)
182            """
183          return self.shapetype          return self.shapetype
184    
185        def GetGeoms(self):
186            """Return the list of geometries of this feature.
187    
188  class OGRShapeStore:          If this feature is a geometry collection, all contained geometries
189            are given. Else the returned list is empty.
190            """
191            return self.geoms
192    
193        def GetGeom(self, index):
194            """Return the OGRGeometry object at the specified index.
195    
196            This is not none only if the shape is a geometry collection.
197            """
198            if index < len(self.geoms):
199                return self.geoms[index]
200            else:
201                return None
202    
203    
204    class OGRGeometry:
205        """This class represents a geometry belonging to a specified feature.
206        """
207    
208        def __init__(self, shape, geom, index):
209            """Initialize the geometry object.
210    
211            shape should be an OGRShape, which this geometry belongs to.
212            geom is the base geometry, index is the ReferenceID.
213            """
214            self.shape = shape
215            self.index = index
216    
217            self.geom = geom.GetGeometryRef(index)
218            try:
219                self.shapetype = ogrlib_shapetypes[self.geom.GetGeometryType()]
220            except:
221                self.shapetype = ogrlib_shapetypes[ogr.wkbUnknown]
222    
223    
224        def ShapeType(self):
225            """Return the shapetype of this geometry object."""
226            return self.shapetype
227    
228      """Corresponds to an OGRLayer object, containing features/shapes and  
229         providing all methods Thuban needs.  class OGRShapeStore:
230        """Corresponds to an OGRLayer object, containing features/shapes and
231           providing the same methods like ShapefileStore.
232      """      """
233    
234      def __init__(self, filename, layername, id_column = None):      def __init__(self, session, filename, layername, id_column = None):
235          # Make the filename absolute. The filename will be          """Initialize the shapestore.
         # interpreted relative to that anyway, but when saving a  
         # session we need to compare absolute paths and it's usually  
         # safer to always work with absolute paths.  
236    
237          self.filename = filename          All required information is loaded from the datasource.
238            """
239            # if id_column is None, data is loaded from file, so we need path
240            # if id_column is not None, data is loaded from database
241            if id_column is None:
242                self.filename = os.path.abspath(filename)
243            else:
244                self.filename = filename
245          self.layername = layername          self.layername = layername
246    
247          self.ogrdatasource = ogr.Open(filename)          self.ogrdatasource = ogr.Open(filename)
248          self.ogrlayer = (self.ogrdatasource).GetLayerByName(layername)          self.ogrlayer = (self.ogrdatasource).GetLayerByName(layername)
249    
250          driver = self.ogrdatasource.GetDriver().GetName()          if id_column is not None:
251          if driver == 'PostgreSQL':              self.id_column = id_column
             self.id_column = 'gid'  
252          else:          else:
253              self.id_column = 'fid'              self.id_column = None
254    
255          self.table = OGRTable(self.ogrdatasource, self.ogrlayer, self.id_column)          self.table = OGRTable(session, self.ogrdatasource, self.ogrlayer,
256                                    self.id_column)
257    
258          self._open_ogrlayer(layername)          self._open_ogrlayer(layername)
259    
260      def _open_ogrlayer(self, layername):      def _open_ogrlayer(self, layername):
261            """Get all required information from the datasource.
262            """
263          self.numshapes = self.ogrlayer.GetFeatureCount()          self.numshapes = self.ogrlayer.GetFeatureCount()
264          self.shapetype = self.ogrlayer.GetLayerDefn().GetGeomType()          self.shapetype = self.ogrlayer.GetLayerDefn().GetGeomType()
265    
# Line 169  class OGRShapeStore: Line 269  class OGRShapeStore:
269          else:          else:
270              self.bbox = None              self.bbox = None
271    
272          if self.shapetype is not ogr.wkbUnknown:          try:
273              self.shapetype = ogrlib_shapetypes[self.shapetype]              self.shapetype = ogrlib_shapetypes[self.shapetype]
274          #else:          except:
275              # this should be ogr.wkbUnknown, but Thuban does not know how              # if shapetype is not contained in ogrlib_shapetypes
276              # to handle an unknown shapetype (e.g. Session Tree)              # treat it like SHAPETYPE_UNKNOWN
277              #self.shapetype = ogrlib_shapetypes[ogr.wkbPoint]              self.shapetype = ogrlib_shapetypes[ogr.wkbUnknown]
278    
279            self.shapes = self.shapes()
280    
281        def shapes(self):
282            """Return a collection of all features as OGRShape objects.
283            """
284            shapes = {}
285            self.ogrlayer.ResetReading()
286            if self.id_column is None:
287                nextFeature = self.ogrlayer.GetNextFeature()
288                while nextFeature is not None:
289                    fid = nextFeature.GetFID()
290                    shape = OGRShape(self, nextFeature)
291                    shapes[shape.ShapeID()] = shape
292                    nextFeature = self.ogrlayer.GetNextFeature()
293            else:
294                lay = self.ogrdatasource.ExecuteSQL("SELECT %s, * from %s"
295                                        % (self.id_column, self.layername))
296                if lay is not None:
297                    lay.ResetReading()
298                    nextFeature = lay.GetNextFeature()
299                    while nextFeature is not None:
300                        fid = nextFeature.GetField(0)
301                        shape = OGRShape(self, nextFeature)
302                        shapes[shape.ShapeID()] = shape
303                        nextFeature = lay.GetNextFeature()
304                    self.ogrdatasource.ReleaseResultSet(lay)
305            return shapes
306    
307      def OGRLayer(self):      def OGRLayer(self):
308          """Return the OGRLayer object"""          """Return the OGRLayer object
309            """
310          return self.ogrlayer          return self.ogrlayer
311    
312      def FileName(self):      def FileName(self):
313          """Return the filename used to open the file"""          """Return the filename used to open the file
314            """
315          return self.filename          return self.filename
316    
317      def FileType(self):      def FileType(self):
318          """Return the filetype. This is always the string 'ogr-file'"""          """Return the filetype. This is depending on the driver used to open
319          return "ogr-file"          the file.
320            """
321            return self.ogrdatasource.GetDriver().GetName()
322    
323      def ShapeType(self):      def ShapeType(self):
324          """Return the type of the shapes in the shapestore.          """Return the type of the shapes in the shapestore.
325    
326          This is either SHAPETYPE_POINT, SHAPETYPE_ARC or SHAPETYPE_POLYGON.          This is either SHAPETYPE_POINT, SHAPETYPE_ARC, SHAPETYPE_POLYGON,
327            SHAEPTYPE_GEOMCOLL, SHAPETYPE_NONE or SHAPETYPE_UNKNOWN.
328          """          """
329          return self.shapetype          return self.shapetype
330    
331      def RawShapeFormat(self):      def RawShapeFormat(self):
332          """Return the raw data format of the shape data, i.e. RAW_PYTHON"""          """Return the raw data format of the shape data, i.e. RAW_PYTHON
333            """
334          return RAW_PYTHON          return RAW_PYTHON
335    
336      def NumShapes(self):      def NumShapes(self):
337          """Return the number of shapes in the shape store"""          """Return the number of shapes in the shape store
338            """
339          return self.numshapes          return self.numshapes
340    
341      def BoundingBox(self):      def BoundingBox(self):
# Line 214  class OGRShapeStore: Line 349  class OGRShapeStore:
349          The bbox parameter should be the bounding box as a tuple in the          The bbox parameter should be the bounding box as a tuple in the
350          form (minx, miny, maxx, maxy) in the coordinate system of the          form (minx, miny, maxx, maxy) in the coordinate system of the
351          shape store.          shape store.
   
         The method GetFID() returns feature IDs starting from 0.  
352          """          """
         # Bind a few globals to locals to make it a bit faster  
         cls = OGRShape  
         ogrlayer = self.ogrlayer  
   
353          left, bottom, right, top = bbox          left, bottom, right, top = bbox
354    
355          # create a geometry which can be passed to the layer as spatial filter          # create a geometry which can be passed to the layer as spatial filter
356          bboxpolygon = ogr.CreateGeometryFromWkt(          bboxpolygon = ogr.CreateGeometryFromWkt(
357                        ('Polygon((%s %s, %s %s, %s %s,%s %s, %s %s))'                        ('Polygon((%s %s, %s %s, %s %s,%s %s, %s %s))'
358                                   %(left, bottom, left, top, right, top,                                   %(left, bottom, left, top, right, top,
359                                    right, bottom, left, bottom)))                                    right, bottom, left, bottom)))
360    
361          if ogrlayer.GetSpatialRef():          if self.ogrlayer.GetSpatialRef():
362              bboxpolygon.AssignSpatialReference(ogrlayer.GetSpatialRef())              bboxpolygon.AssignSpatialReference(self.ogrlayer.GetSpatialRef())
363    
364          ogrlayer.ResetReading()          self.ogrlayer.ResetReading()
365          #ogrlayer.SetSpatialFilterRect(left, bottom, right, top)          #ogrlayer.SetSpatialFilterRect(left, bottom, right, top)
366          ogrlayer.SetSpatialFilter(bboxpolygon)          self.ogrlayer.SetSpatialFilter(bboxpolygon)
367    
368          numFeatures = ogrlayer.GetFeatureCount()          numFeatures = self.ogrlayer.GetFeatureCount()
369            # if no features are in bbox, return all features as shapesInRegion
370            # (PostGIS sometimes returns no features even if they are within
371            #  the bounding box)
372            if numFeatures == 0:
373                self.ogrlayer.SetSpatialFilter(None)
374                numFeatures = self.ogrlayer.GetFeatureCount()
375          for feature in range(numFeatures):          for feature in range(numFeatures):
376              nextFeature = ogrlayer.GetNextFeature()              nextFeature = self.ogrlayer.GetNextFeature()
377              yield cls(ogrlayer, nextFeature.GetFID())              if self.id_column is None:
378                    yield self.shapes[nextFeature.GetFID()]
379                else:
380                    yield self.shapes[nextFeature.GetField(self.id_column)]
381    
382          ogrlayer.SetSpatialFilter(None)          self.ogrlayer.SetSpatialFilter(None)
383          bboxpolygon.Destroy()          bboxpolygon.Destroy()
384    
385      def AllShapes(self):      def AllShapes(self):
386          """Return an iterable over the shapes in the shape store."""          """Return an iterable over the shapes in the shape store.
387          self.ogrlayer.ResetReading()          """
388          nextFeature = self.ogrlayer.GetNextFeature()          for id in range(len(self.shapes)):
389          while nextFeature is not None:              yield self.shapes[id]
             yield OGRShape(self.ogrlayer, nextFeature.GetFID())  
             nextFeature = self.ogrlayer.GetNextFeature()  
390    
391      def Shape(self, index):      def Shape(self, fid):
392          """Return the shape with index index"""          """Return the shape with fid = fid
393          return OGRShape(self.ogrlayer, index)          """
394            if fid in self.table.ids.keys():
395                return self.shapes[fid]
396            else:
397                return None
398    
399      def Table(self):      def Table(self):
400          """Return the table containing the attribute data"""          """Return the table containing the attribute data
401            """
402          return self.table          return self.table
403    
404      def Dependencies(self):      def Dependencies(self):
405          """Return the empty tuple."""          """Return the empty tuple.
406            """
407          return ()          return ()
408    
409      def OrigShapeStore(self):      def OrigShapeStore(self):
# Line 268  class OGRShapeStore: Line 411  class OGRShapeStore:
411          return None          return None
412    
413      def Id_column(self):      def Id_column(self):
414          """Return the id_column."""          """Return the id_column.
415            """
416          return self.id_column          return self.id_column
417    
418  class OGRTable:  class OGRTable(transientdb.AutoTransientTable):
419        """A Table for an ogr datasource.
     """A Table for an ogr file  
420      """      """
421    
422      def __init__(self, ds, layer, id_column):      def __init__(self, session, ds, layer, id_column):
423          """Initialize the OGRTable.          """Initialize the OGRTable.
424    
425          ds should be an instance of OGRDatasource.          session   - should be the current session.
426          layer should be an instance of OGRLayer.          ds        - should be an instance of OGRDatasource.
427            layer     - should be an instance of OGRLayer.
428            id_column - should be the name of the column used as ID column
429          """          """
   
430          self.datasource = ds          self.datasource = ds
431          self.layer = layer          self.layer = layer
432          self.tablename = layer.GetName()          self.tablename = self.layer.GetName()
433          self.id_column = id_column          self.id_column = id_column
434    
435          # Map column names and indices to column objects.          # Map column names and indices to column objects.
# Line 295  class OGRTable: Line 439  class OGRTable:
439          self._map_ords_and_ids()          self._map_ords_and_ids()
440    
441          self._fetch_table_information()          self._fetch_table_information()
442            self._fetch_table_content()
443    
444            transientdb.AutoTransientTable.__init__(self, session.TransientDB(),
445                                                    self)
446    
447      def _fetch_table_information(self):      def _fetch_table_information(self):
448          """Internal: Update information about the table"""          """Internal: Update information about the table
449            """
450          self.columns = []          self.columns = []
451    
452          layerdefn = self.layer.GetLayerDefn()          layerdefn = self.layer.GetLayerDefn()
453            # if FID column is of interest
454            #col = OGRColumn("FID", table.FIELDTYPE_INT, layerdefn.GetFieldCount())
455            #self.columns.append(col)
456          for i in range(layerdefn.GetFieldCount()):          for i in range(layerdefn.GetFieldCount()):
457              fielddef = layerdefn.GetFieldDefn(i)              fielddef = layerdefn.GetFieldDefn(i)
458              fieldname = fielddef.GetName()              fieldname = fielddef.GetName()
# Line 314  class OGRTable: Line 466  class OGRTable:
466              self.column_map[col.name] = col              self.column_map[col.name] = col
467              self.column_map[col.index] = col              self.column_map[col.index] = col
468    
469        def _fetch_table_content(self):
470            """Internal: Update information contained in the table
471            """
472            self.content = []
473            layerdefn = self.layer.GetLayerDefn()
474    
475            self.layer.ResetReading()
476            for i in range(self.layer.GetFeatureCount()):
477                nextFeature = self.layer.GetNextFeature()
478                row = []
479                for j in range(layerdefn.GetFieldCount()):
480                    row.append(nextFeature.GetField(j))
481                # if FID should be listed in the table
482                #if self.id_column is None:
483                #    row.append(nextFeature.GetFID())
484                #else:
485                #    row.append(nextFeature.GetField(self.id_column))
486                self.content.append(row)
487    
488      def _map_ords_and_ids(self):      def _map_ords_and_ids(self):
489            """Create collections which map ordinals to ids and verse visa.
490            """
491          self.ordinals = {}          self.ordinals = {}
492          self.ids = {}          self.ids = {}
493    
494          lay = self.datasource.ExecuteSQL(          if self.id_column is not None:
495                  "SELECT %s from %s"              lay = self.datasource.ExecuteSQL("SELECT %s from %s"
496                  %(self.id_column, self.tablename))                      %(self.id_column, self.tablename))
497          lay.ResetReading()              lay.ResetReading()
498          nextFeature = lay.GetNextFeature()              nextFeature = lay.GetNextFeature()
499            else:
500                self.layer.ResetReading()
501                nextFeature = self.layer.GetNextFeature()
502    
503          ord = 0          ord = 0
504          while nextFeature is not None:          while nextFeature is not None:
505              id = nextFeature.GetFID()              if self.id_column is not None:
506                    id = nextFeature.GetField(self.id_column)
507                    nextFeature = lay.GetNextFeature()
508                else:
509                    id = nextFeature.GetFID()
510                    nextFeature = self.layer.GetNextFeature()
511              self.ordinals[ord] = id              self.ordinals[ord] = id
512              self.ids[id] = ord              self.ids[id] = ord
             nextFeature = lay.GetNextFeature()  
513              ord = ord + 1              ord = ord + 1
514          self.datasource.ReleaseResultSet(lay)          if self.id_column is not None:
515                self.datasource.ReleaseResultSet(lay)
516    
517      def TableName(self):      def TableName(self):
518          """Return the name of the table, which is the name of the layer"""          """Return the name of the table, which is the name of the layer
519            """
520          return self.tablename          return self.tablename
521    
522      def Title(self):      def Title(self):
523          """Return the title of the table.          """Return the title of the table.
   
         The title is currently  
524          """          """
525          return self.tablename          return self.tablename
526    
527      def Dependencies(self):      def Dependencies(self):
528          """Return an empty tuple."""          """Return an empty tuple.
529            """
530          return ()          return ()
531    
532      def NumColumns(self):      def NumColumns(self):
533          """Return the number of columns."""          """Return the number of columns.
534            """
535          return len(self.columns)          return len(self.columns)
536    
537      def Columns(self):      def Columns(self):
538          """Return all columns."""          """Return all columns.
539            """
540          return self.columns          return self.columns
541    
542      def Column(self, col):      def Column(self, col):
543          """Return the column col. col can be either a string or an integer."""          """Return the column col. col can be either a string or an integer.
544            """
545          return self.column_map[col]          return self.column_map[col]
546    
547      def HasColumn(self, col):      def HasColumn(self, col):
548          """Return if column col exists. col can be either a string or an          """Return if column col exists. col can be either a string or an
549          integer.          integer.
550          """          """
551          return self.column_map.has_key(col)          return self.column_map.has_key(col)
552    
553      def NumRows(self):      def NumRows(self):
554          """Return the number of rows in the table, which equals the number of          """Return the number of rows in the table, which equals the number of
555          features in the layer.          features in the layer.
556          """          """
557          return self.layer.GetFeatureCount()          return len(self.ids)
558    
559      def RowIdToOrdinal(self, gid):      def RowIdToOrdinal(self, gid):
560          """Return the row ordinal given its id"""          """Return the row ordinal given its id
561            """
562          if gid < 0:          if gid < 0:
563              return gid              return gid
564          else:          else:
565              ord = self.ids[gid]              ord = self.ids[gid]
566              return ord              return ord
 #        lay = self.datasource.ExecuteSQL(  
  #               "SELECT COUNT(%s) From %s where FID < %s"  
   #              %(self.id_column, self.tablename, gid))  
    #     ord = lay.GetFeature(0).GetField(0)  
     #    self.datasource.ReleaseResultSet(lay)  
  #       return ord  
567    
568      def RowOrdinalToId(self, num):      def RowOrdinalToId(self, num):
569          """Return the rowid for given its ordinal"""          """Return the rowid for given its ordinal
570  #        lay = self.datasource.ExecuteSQL(          """
  #               "SELECT FID From %s"  
   #              %(self.tablename))  
    #     for i in range(num):  
     #        lay.GetNextFeature()  
      #   id = lay.GetNextFeature().GetField(0)  
       #  self.datasource.ReleaseResultSet(lay)  
571          if num >= 0:          if num >= 0:
572              id = self.ordinals[num]              id = self.ordinals[num]
573              return id              return id
# Line 401  class OGRTable: Line 575  class OGRTable:
575              return num              return num
576    
577      def ReadRowAsDict(self, row, row_is_ordinal = 0):      def ReadRowAsDict(self, row, row_is_ordinal = 0):
578          """Return a dictionary which contains all the fields."""          """Return a dictionary which contains all the fields.
579          if row_is_ordinal == 1:          """
580              rowId = self.RowOrdinalToId(row)          if row_is_ordinal == 0:
581                rowId = self.RowIdToOrdinal(row)
582          else:          else:
583              rowId = row              rowId = row
         layerdef = self.layer.GetLayerDefn()  
         feature = self.layer.GetFeature(rowId)  
584          result = {}          result = {}
585          for i in range(len(self.columns)):          for i in range(self.NumColumns()):
586              fielddef = layerdef.GetFieldDefn(i)              result[self.Column(i).name] = self.content[rowId][i]
             if feature is not None:  
                 result[self.columns[i].name] = feature.GetField(i)  
             else:  
                 result[fielddef.GetName()] = None  
587          return result          return result
588    
589      def ReadValue(self, row, col, row_is_ordinal = 0):      def ReadValue(self, row, col, row_is_ordinal = 0):
590          """Return the requested value."""          """Return the requested value.
591          if col is None:          """
592              return None          if row_is_ordinal == 0:
593                rowId = self.RowIdToOrdinal(row)
594          else:          else:
595              feature = self.layer.GetFeature(row)              rowId = row
596          return feature.GetField(col)          colIndex = self.column_map[col].index
597            return self.content[rowId][colIndex]
598    
599      def ValueRange(self, col):      def ValueRange(self, col):
600          """Return the value range of the given column (given as string)."""          """Return the value range of the given column (given as string).
601            """
602    
603          result = self.datasource.ExecuteSQL("SELECT min(%s), max(%s) FROM %s"          result = self.datasource.ExecuteSQL("SELECT min(%s), max(%s) FROM %s"
604                  %(col, col, self.layer.GetName()))                  %(col, col, self.layer.GetName()))
605          result.ResetReading()          result.ResetReading()
# Line 456  class OGRTable: Line 629  class OGRTable:
629          return values          return values
630    
631      def SimpleQuery(self, left, comparison, right):      def SimpleQuery(self, left, comparison, right):
632          """Return the FIDs resulting from the given query."""          """Return the FIDs resulting from the given query.
633            """
634    
635          if comparison not in ("==", "!=", "<", "<=", ">=", ">"):          if comparison not in ("==", "!=", "<", "<=", ">=", ">"):
636              raise ValueError("Comparison operator %r not allowed" %comparison)              raise ValueError("Comparison operator %r not allowed" %comparison)
637    
# Line 468  class OGRTable: Line 643  class OGRTable:
643          else:          else:
644              right_template = right              right_template = right
645    
646          query = ("SELECT %s FROM %s WHERE '%s' %s %s ORDER BY FID"          if self.id_column is None:
647                  % (self.id_column, self.tablename,left.name, comparison,              id = "FID"
648                     right_template))          else:
649                id = self.id_column
650            query = ("SELECT %s FROM %s WHERE %s %s %s ORDER BY %s"
651                    % (id, self.tablename,left.name, comparison,
652                       right_template, id))
653    
654          lay = self.datasource.ExecuteSQL(query)          lay = self.datasource.ExecuteSQL(query)
655          result = []          result = []
# Line 484  class OGRTable: Line 663  class OGRTable:
663          return result          return result
664    
665      def Id_column(self):      def Id_column(self):
666          """Return the id_column."""          """Return the id_column.
667            """
668          return self.id_column          return self.id_column
669    
670    
671  class OGRColumn:  class OGRColumn:
   
672      """Column description for a table for an ogr file      """Column description for a table for an ogr file
673      """      """
674    

Legend:
Removed from v.2559  
changed lines
  Added in v.2577

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26