/[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 2493 by nhueffme, Mon Dec 20 14:13:57 2004 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    
   
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 36  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,
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            shapestore should be an instance of OGRShapeStore,
70            shape should be an instance of an OGRFeature.
71            """
72            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()
80            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            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            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 __init__(self, ogrlayer, shapeid):      def _compute_bbox(self):
108          self.ogrlayer = ogrlayer          """
109          self.shapeid = shapeid          Compute the bounding box of the shape as a tuple (minx,miny,maxx,maxy)
110            """
111            minx, maxx, miny, maxy = self.geom.GetEnvelope()
112            return (minx, miny, maxx, maxy)
113    
114      def compute_bbox(self):      def compute_bbox(self):
115          """          """
116          Return the bounding box of the shape as a tuple (minx,miny,maxx,maxy)          Return the bounding box of the shape as a tuple (minx,miny,maxx,maxy)
117          """          """
118          shape = self.ogrlayer.GetFeature(self.shapeid)          return self.bbox
         geom = shape.GetGeometryRef()  
         minx, maxx, miny, maxy = geom.GetEnvelope()  
         return (minx, miny, maxx, maxy)  
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    
     # diese Methode funktioniert vielleicht noch nicht f�r andere Formate  
     #als shp  
     #(wenn ein polygon aus mehreren  
     # Ringen besteht o.�., hat ein Geometry-Objekt mehr als einen  
     #GeometryRef().---------  
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          feature = self.ogrlayer.GetFeature(self.shapeid)          """
128          geom = feature.GetGeometryRef()          return self.points
129    
130        def _points(self):
131            """Get the coordinates of the shape as a list of lists of pairs
132            """
133          shape = []          shape = []
134    
135            if self.geom is None:
136                return shape.append([])
137    
138          # if geometry object is of type point or line          # if geometry object is of type point or line
139          if geom.GetGeometryCount() == 0:          if self.geom.GetGeometryCount() == 0:
140              points =[]              points =[]
141              for point in range(geom.GetPointCount()):              for point in range(self.geom.GetPointCount()):
142                  x = geom.GetX(point)                  x = self.geom.GetX(point)
143                  y = geom.GetY(point)                  y = self.geom.GetY(point)
144                  points.append((x, y))                  points.append((x, y))
145              return [points]              return [points]
146          # if geometry object is of type polygon or multipolygon          # if geometry object is of type polygon or multipolygon
147          for i in range(geom.GetGeometryCount()):          for i in range(self.geom.GetGeometryCount()):
148              points = []              points = []
149              geometry = geom.GetGeometryRef(i)              geometry = self.geom.GetGeometryRef(i)
150              # if geometry object is polygon              # if geometry object is polygon
151              if geometry.GetGeometryCount() == 0:              if geometry.GetGeometryCount() == 0:
152                  for point in range(geometry.GetPointCount()):                  for point in range(geometry.GetPointCount()):
153                      x = geometry.GetX(point)                      x = geometry.GetX(point)
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 = []
161                      subgeom = geometry.GetGeometryRef(j)                      subgeom = geometry.GetGeometryRef(j)
# Line 108  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):
180            """Return the shapetype of this shape (may differ from the layer's
181            shapetype)
182            """
183            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      """Corresponds to an OGRLayer object, containing features/shapes and          self.geom = geom.GetGeometryRef(index)
218         providing all methods Thuban needs.          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    
229    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, session, filename, layername):      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 = os.path.abspath(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(self.filename)          self.ogrdatasource = ogr.Open(filename)
248          self.ogrlayer = (self.ogrdatasource).GetLayerByName(layername)          self.ogrlayer = (self.ogrdatasource).GetLayerByName(layername)
249          self.table = OGRTable(self.ogrdatasource, self.ogrlayer)  
250            if id_column is not None:
251                self.id_column = id_column
252            else:
253                self.id_column = None
254    
255            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()
         extent = self.ogrlayer.GetExtent()  
265    
266            extent = self.ogrlayer.GetExtent()
267          if extent:          if extent:
268              self.bbox = [extent[0], extent[2], extent[1], extent[3]]              self.bbox = [extent[0], extent[2], extent[1], extent[3]]
269          else:          else:
270              self.bbox = None              self.bbox = None
271    
272          self.shapetype = ogrlib_shapetypes[self.shapetype]          try:
273                self.shapetype = ogrlib_shapetypes[self.shapetype]
274            except:
275                # if shapetype is not contained in ogrlib_shapetypes
276                # treat it like SHAPETYPE_UNKNOWN
277                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 187  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.SetSpatialFilter(bboxpolygon)          #ogrlayer.SetSpatialFilterRect(left, bottom, right, top)
366          numFeatures = ogrlayer.GetFeatureCount()          self.ogrlayer.SetSpatialFilter(bboxpolygon)
367    
368            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          ogrlayer.SetSpatialFilter(None)                  yield self.shapes[nextFeature.GetFID()]
379                else:
380                    yield self.shapes[nextFeature.GetField(self.id_column)]
381    
382            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          for i in xrange(self.NumShapes()):          """
388              yield OGRShape(self.ogrlayer, i)          for id in range(len(self.shapes)):
389                yield self.shapes[id]
390      def Shape(self, index):  
391          """Return the shape with index index"""      def Shape(self, fid):
392          return OGRShape(self.ogrlayer, index)          """Return the shape with fid = fid
393            """
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):
410          """Return None."""          """Return None."""
411          return None          return None
412    
413        def Id_column(self):
414            """Return the id_column.
415            """
416            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):      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
434    
435          # Map column names and indices to column objects.          # Map column names and indices to column objects.
436          self.column_map = {}          self.column_map = {}
437    
438            # Map feature ids to ordinals.
439            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 275  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):
489            """Create collections which map ordinals to ids and verse visa.
490            """
491            self.ordinals = {}
492            self.ids = {}
493    
494            if self.id_column is not None:
495                lay = self.datasource.ExecuteSQL("SELECT %s from %s"
496                        %(self.id_column, self.tablename))
497                lay.ResetReading()
498                nextFeature = lay.GetNextFeature()
499            else:
500                self.layer.ResetReading()
501                nextFeature = self.layer.GetNextFeature()
502    
503            ord = 0
504            while nextFeature is not None:
505                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
512                self.ids[id] = ord
513                ord = ord + 1
514            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 fixed and equal to the tablename  
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          return self.layer.GetFeature(gid).GetFID()          """
562            if gid < 0:
563                return gid
564            else:
565                ord = self.ids[gid]
566                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          return self.layer.GetFeature(num).GetFID()          """
571            if num >= 0:
572                id = self.ordinals[num]
573                return id
574            else:
575                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          layerdef = self.layer.GetLayerDefn()          """
580          feature = self.layer.GetFeature(row)          if row_is_ordinal == 0:
581                rowId = self.RowIdToOrdinal(row)
582            else:
583                rowId = row
584          result = {}          result = {}
585          for i in range(feature.GetFieldCount()):          for i in range(self.NumColumns()):
586              fielddef = layerdef.GetFieldDefn(i)              result[self.Column(i).name] = self.content[rowId][i]
             result[fielddef.GetName()] = feature.GetField(i)  
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 371  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 383  class OGRTable: Line 643  class OGRTable:
643          else:          else:
644              right_template = right              right_template = right
645    
646          query = ("SELECT FID FROM %s WHERE '%s' %s %s ORDER BY FID"          if self.id_column is None:
647                  % (self.tablename,left.name, comparison, right_template))              id = "FID"
648            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 393  class OGRTable: Line 658  class OGRTable:
658              if feature is None:              if feature is None:
659                  break                  break
660              result.append(feature.GetField(0))              result.append(feature.GetField(0))
661          self.datasource.ReleaseResultSet(lay)          if lay is not None:
662                self.datasource.ReleaseResultSet(lay)
663          return result          return result
664    
665        def Id_column(self):
666            """Return the id_column.
667            """
668            return self.id_column
669    
 class OGRColumn:  
670    
671    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.2493  
changed lines
  Added in v.2577

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26