/[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 2437 by silke, Wed Dec 8 17:37:30 2004 UTC revision 2577 by nhueffme, Fri Mar 4 15:07:59 2005 UTC
# Line 1  Line 1 
1  # Copyright (C) 2004 by Intevation GmbH  # Copyright (C) 2004 by Intevation GmbH
2  # Authors:  # Authors:
3  # Nina H�ffmeyer <[email protected]>  # Nina Hueffmeyer <[email protected]>
4  #  #
5  # This program is free software under the GPL (>=v2)  # This program is free software under the GPL (>=v2)
6  # Read the file COPYING coming with the software for details.  # Read the file COPYING coming with the software for details.
# 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    
 # Raw data in ogr format  
 RAW_OGRSHAPES = "RAW_OGRSHAPES"  
   
   
   
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 40  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      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.shapeid = shapeid          """
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 _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()
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          geometry = feature.GetGeometryRef()          return self.points
129          while geometry.GetGeometryCount() != 0:  
130                  geometry = geometry.GetGeometryRef(0)      def _points(self):
131          points = []          """Get the coordinates of the shape as a list of lists of pairs
132          for point in range(geometry.GetPointCount()):          """
133                  x = geometry.GetX(point)          shape = []
134                  y = geometry.GetY(point)  
135                  points.append((x, y))          if self.geom is None:
136          points = [points]              return shape.append([])
137          return points  
138            # if geometry object is of type point or line
139            if self.geom.GetGeometryCount() == 0:
140                points =[]
141                for point in range(self.geom.GetPointCount()):
142                    x = self.geom.GetX(point)
143                    y = self.geom.GetY(point)
144                    points.append((x, y))
145                return [points]
146            # if geometry object is of type polygon or multipolygon
147            for i in range(self.geom.GetGeometryCount()):
148                points = []
149                geometry = self.geom.GetGeometryRef(i)
150                # if geometry object is polygon
151                if geometry.GetGeometryCount() == 0:
152                    for point in range(geometry.GetPointCount()):
153                        x = geometry.GetX(point)
154                        y = geometry.GetY(point)
155                        points.append((x, y))
156                    shape.append(points)
157                # if geometry object is of type multipolygon or geometry collection
158                else:
159                    for j in range(geometry.GetGeometryCount()):
160                        points = []
161                        subgeom = geometry.GetGeometryRef(j)
162                        for point in range(subgeom.GetPointCount()):
163                            x = subgeom.GetX(point)
164                            y = subgeom.GetY(point)
165                            points.append((x, y))
166                        shape.append(points)
167            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            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    
229  class OGRShapeStore:  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, id_column = None):
235            """Initialize the shapestore.
236    
237            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
246    
247      """Corresponds to an OGRLayer object, containing features/shapes and providing all methods Thuban          self.ogrdatasource = ogr.Open(filename)
248         needs."""          self.ogrlayer = (self.ogrdatasource).GetLayerByName(layername)
249    
250      def __init__(self, session, filename, layername):          if id_column is not None:
251          # Make the filename absolute. The filename will be              self.id_column = id_column
252          # interpreted relative to that anyway, but when saving a          else:
253          # session we need to compare absolute paths and it's usually              self.id_column = None
254          # safer to always work with absolute paths.  
255            self.table = OGRTable(session, self.ogrdatasource, self.ogrlayer,
256          self.filename = os.path.abspath(filename)                                  self.id_column)
         self.layername = layername  
   
         self.ogrdatasource = ogr.Open(self.filename)  
         self.ogrlayer = (self.ogrdatasource).GetLayerByName(layername)  
         self.table = OGRTable(self.ogrdatasource, self.ogrlayer)  
257    
258          self._open_ogrlayer(layername)          self._open_ogrlayer(layername)
259    
260      def _open_ogrlayer(self, layername):      def _open_ogrlayer(self, layername):
261          self.numshapes = self.ogrlayer.GetFeatureCount()          """Get all required information from the datasource.
262          self.shapetype = self.ogrlayer.GetLayerDefn().GetGeomType()          """
263          extent = self.ogrlayer.GetExtent()          self.numshapes = self.ogrlayer.GetFeatureCount()
264            self.shapetype = self.ogrlayer.GetLayerDefn().GetGeomType()
265          if extent:  
266                  self.bbox = [extent[0], extent[2], extent[1], extent[3]]          extent = self.ogrlayer.GetExtent()
267          else:          if extent:
268                  self.bbox = None              self.bbox = [extent[0], extent[2], extent[1], extent[3]]
269            else:
270                self.bbox = None
271    
272            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          self.shapetype = ogrlib_shapetypes[self.shapetype]      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_OGRSHAPES"""          """Return the raw data format of the shape data, i.e. RAW_PYTHON
333          return RAW_OGRSHAPES          """
334            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 166  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. In Thuban feature IDs start with 1.  
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('Polygon((%s %s, %s %s, %s %s, %s %s, %s %s))'          bboxpolygon = ogr.CreateGeometryFromWkt(
357                  %(left, bottom, left, top, right, top, right, bottom, left, bottom))                        ('Polygon((%s %s, %s %s, %s %s,%s %s, %s %s))'
358                                     %(left, bottom, left, top, right, top,
359          if ogrlayer.GetSpatialRef():                                    right, bottom, left, bottom)))
360                  bboxpolygon.AssignSpatialReference(ogrlayer.GetSpatialRef())  
361            if self.ogrlayer.GetSpatialRef():
362          ogrlayer.ResetReading()              bboxpolygon.AssignSpatialReference(self.ogrlayer.GetSpatialRef())
363          ogrlayer.SetSpatialFilter(bboxpolygon)  
364          numFeatures = ogrlayer.GetFeatureCount()          self.ogrlayer.ResetReading()
365          for feature in range(numFeatures):          #ogrlayer.SetSpatialFilterRect(left, bottom, right, top)
366                  nextFeature = ogrlayer.GetNextFeature()          self.ogrlayer.SetSpatialFilter(bboxpolygon)
367                  yield cls(ogrlayer, nextFeature.GetFID())  
368          ogrlayer.SetSpatialFilter(None)          numFeatures = self.ogrlayer.GetFeatureCount()
369          bboxpolygon.Destroy()          # 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):
376                nextFeature = self.ogrlayer.GetNextFeature()
377                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            self.ogrlayer.SetSpatialFilter(None)
383            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          for i in range(layerdefn.GetFieldCount()):          # if FID column is of interest
454                  fielddef = layerdefn.GetFieldDefn(i)          #col = OGRColumn("FID", table.FIELDTYPE_INT, layerdefn.GetFieldCount())
455                  fieldname = fielddef.GetName()          #self.columns.append(col)
456                  fieldtype = fieldtype_map[fielddef.GetType()]          for i in range(layerdefn.GetFieldCount()):
457                  fieldindex = layerdefn.GetFieldIndex(fieldname)              fielddef = layerdefn.GetFieldDefn(i)
458                  col = OGRColumn(fieldname, fieldtype, fieldindex)              fieldname = fielddef.GetName()
459                  if col is not None:              fieldtype = fieldtype_map[fielddef.GetType()]
460                          self.columns.append(col)              fieldindex = layerdefn.GetFieldIndex(fieldname)
461                col = OGRColumn(fieldname, fieldtype, fieldindex)
462                if col is not None:
463                    self.columns.append(col)
464    
465          for col in self.columns:          for col in self.columns:
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 integer."""          """Return if column col exists. col can be either a string or an
549            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 features in the layer."""          """Return the number of rows in the table, which equals the number of
555          return self.layer.GetFeatureCount()          features in the layer.
556            """
557            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          result = {}              rowId = self.RowIdToOrdinal(row)
582          for i in range(feature.GetFieldCount()):          else:
583                  fielddef = layerdef.GetFieldDefn(i)              rowId = row
584                  result[fielddef.GetName()] = feature.GetField(i)          result = {}
585            for i in range(self.NumColumns()):
586                result[self.Column(i).name] = self.content[rowId][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          else:              rowId = self.RowIdToOrdinal(row)
594                  feature = self.layer.GetFeature(row)          else:
595                  return feature.GetField(col)              rowId = row
596            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          result = self.datasource.ExecuteSQL("SELECT min(%s), max(%s) FROM %s"          """
602                  %(col, col, self.layer.GetName()))  
603          result.ResetReading()          result = self.datasource.ExecuteSQL("SELECT min(%s), max(%s) FROM %s"
604          feature = result.GetNextFeature()                  %(col, col, self.layer.GetName()))
605          try:          result.ResetReading()
606                  min = feature.GetField(0)          feature = result.GetNextFeature()
607                  max = feature.GetField(1)          try:
608          except:              min = feature.GetField(0)
609                  min = 0              max = feature.GetField(1)
610                  max = 0          except:
611          self.datasource.ReleaseResultSet(result)              min = 0
612                max = 0
613            self.datasource.ReleaseResultSet(result)
614          return (min, max)          return (min, max)
615    
616      def UniqueValues(self, col):      def UniqueValues(self, col):
617          """Return all the values being found in the column (given as string)."""          """Return all the values being found in the column (given as string).
618          result = self.datasource.ExecuteSQL("SELECT DISTINCT %s FROM %s ORDER BY %s" %(col, self.layer.GetName(),col))          """
619          values = []          result = self.datasource.ExecuteSQL((
620          while 1:                      "SELECT DISTINCT %s FROM %s ORDER BY %s"
621                  feature = result.GetNextFeature()                       %(col,self.layer.GetName(),col)))
622                  if feature is None:          values = []
623                          break          while 1:
624                  values.append(feature.GetField(0))              feature = result.GetNextFeature()
625          self.datasource.ReleaseResultSet(result)              if feature is None:
626                    break
627                values.append(feature.GetField(0))
628            self.datasource.ReleaseResultSet(result)
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    
638          if comparison == "==":          if comparison == "==":
639              comparison = "="              comparison = "="
# Line 353  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" %(self.tablename, left.name, comparison, right_template)          if self.id_column is None:
647                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 = []
656          while 1:          while lay is not None:
657              feature = lay.GetNextFeature()              feature = lay.GetNextFeature()
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.2437  
changed lines
  Added in v.2577

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26