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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2608 - (hide annotations)
Thu Apr 28 09:39:08 2005 UTC (19 years, 10 months ago) by jan
Original Path: trunk/thuban/Extensions/ogr/ogrshapes.py
File MIME type: text/x-python
File size: 27488 byte(s)
(OGRFileShapeStore): New. This
class ist to be used for any file-based shape stores
accessed through OGR.

1 nhueffme 2435 # Copyright (C) 2004 by Intevation GmbH
2     # Authors:
3 nhueffme 2493 # Nina Hueffmeyer <[email protected]>
4 nhueffme 2435 #
5     # This program is free software under the GPL (>=v2)
6     # Read the file COPYING coming with the software for details.
7    
8     __version__ = "$Revision$"
9     # $Source$
10     # $Id$
11    
12     from __future__ import generators
13    
14     try:
15     import ogr
16     except ImportError:
17     ogr = None
18    
19     import os
20    
21     from Thuban import _
22     from Thuban.Model import table
23 nhueffme 2577 from Thuban.Model import transientdb
24     from Thuban.Model.transientdb import TransientDatabase
25 nhueffme 2435
26     from Thuban.Model.data import SHAPETYPE_POLYGON, SHAPETYPE_ARC, SHAPETYPE_POINT
27     from Thuban.Model.data import RAW_PYTHON, RAW_SHAPEFILE, RAW_WKT
28 jan 2608 from Thuban.Model.data import FileShapeStore
29 nhueffme 2435
30     def has_ogr_support():
31     """Return whether this Thuban instance supports ogr file formats
32    
33     Having OGR support means that the ogr module can be
34     imported.
35     """
36     return ogr is not None
37    
38     if ogr is not None:
39 nhueffme 2577 SHAPETYPE_UNKNOWN = ogr.wkbUnknown
40     SHAPETYPE_GEOMCOLL = ogr.wkbGeometryCollection
41     SHAPETYPE_NONE = ogr.wkbNone
42    
43     # mapping from ogr-lib shapetypes and table constants to our constants
44 nhueffme 2435 ogrlib_shapetypes = {ogr.wkbPolygon: SHAPETYPE_POLYGON,
45 nhueffme 2493 ogr.wkbLineString: SHAPETYPE_ARC,
46 nhueffme 2549 ogr.wkbPoint: SHAPETYPE_POINT,
47 nhueffme 2577 ogr.wkbUnknown: SHAPETYPE_UNKNOWN,
48     ogr.wkbNone: SHAPETYPE_NONE,
49     ogr.wkbGeometryCollection: SHAPETYPE_GEOMCOLL}
50 nhueffme 2435
51     fieldtype_map = {ogr.OFTString: table.FIELDTYPE_STRING,
52 nhueffme 2493 ogr.OFTInteger: table.FIELDTYPE_INT,
53     ogr.OFTReal: table.FIELDTYPE_DOUBLE}
54 nhueffme 2435
55 nhueffme 2577 else:
56     ogrlib_shapetypes = {}
57     fieldtype_map = {}
58     SHAPETYPE_UNKNOWN = 0
59     SHAPETYPE_GEOMCOLL = 7
60     SHAPETYPE_NONE = 100
61 nhueffme 2435
62 nhueffme 2577
63 nhueffme 2435 class OGRShape:
64 nhueffme 2577 """Represent one shape of an OGRShapeStore
65     """
66 nhueffme 2435
67 nhueffme 2577 def __init__(self, shapestore, shape):
68     """Initialize the shape object.
69 nhueffme 2435
70 nhueffme 2577 shapestore should be an instance of OGRShapeStore,
71     shape should be an instance of an OGRFeature.
72     """
73     self.ogrlayer = shapestore.ogrlayer
74     id_column = shapestore.Id_column()
75     self.feature = shape
76     if id_column is None:
77     self.shapeid = self.feature.GetFID()
78     else:
79     self.shapeid = self.feature.GetField(id_column)
80 nhueffme 2559 self.geom = self.feature.GetGeometryRef()
81 nhueffme 2577 if self.geom:
82     self.shapetype = self.geom.GetGeometryType()
83     self.bbox = self._compute_bbox()
84     self.points = self._points()
85     else:
86     self.shapetype = ogr.wkbNone
87     self.bbox = None
88     self.points = [[]]
89     try:
90     self.shapetype = ogrlib_shapetypes[self.shapetype]
91     except:
92     self.shapetype = ogrlib_shapetypes[ogr.wkbUnknown]
93 nhueffme 2435
94 nhueffme 2577 self.geoms = self._geoms()
95    
96     def _geoms(self):
97     """Return a list of geometry objects.
98    
99     If the shape is a geometry collection, all contained geometry
100     objects are stored to the list as OGRGeometry objects.
101 nhueffme 2435 """
102 nhueffme 2577 geoms = []
103     if self.shapetype == SHAPETYPE_GEOMCOLL:
104     for i in range(self.geom.GetGeometryCount()):
105     geoms.append(OGRGeometry(self, self.geom, i))
106     return geoms
107    
108     def _compute_bbox(self):
109 nhueffme 2435 """
110 nhueffme 2577 Compute the bounding box of the shape as a tuple (minx,miny,maxx,maxy)
111     """
112 nhueffme 2559 minx, maxx, miny, maxy = self.geom.GetEnvelope()
113 nhueffme 2493 return (minx, miny, maxx, maxy)
114 nhueffme 2435
115 nhueffme 2577 def compute_bbox(self):
116     """
117     Return the bounding box of the shape as a tuple (minx,miny,maxx,maxy)
118     """
119     return self.bbox
120    
121 nhueffme 2435 def ShapeID(self):
122 nhueffme 2577 """Return the feature id of this shape.
123     """
124 nhueffme 2435 return self.shapeid
125    
126     def Points(self):
127 nhueffme 2577 """Return the coordinates of the shape as a list of lists of pairs
128     """
129     return self.points
130    
131     def _points(self):
132     """Get the coordinates of the shape as a list of lists of pairs
133     """
134 nhueffme 2549 shape = []
135    
136 nhueffme 2559 if self.geom is None:
137 nhueffme 2549 return shape.append([])
138    
139 nhueffme 2493 # if geometry object is of type point or line
140 nhueffme 2559 if self.geom.GetGeometryCount() == 0:
141 nhueffme 2493 points =[]
142 nhueffme 2559 for point in range(self.geom.GetPointCount()):
143     x = self.geom.GetX(point)
144     y = self.geom.GetY(point)
145 nhueffme 2493 points.append((x, y))
146     return [points]
147     # if geometry object is of type polygon or multipolygon
148 nhueffme 2559 for i in range(self.geom.GetGeometryCount()):
149 nhueffme 2493 points = []
150 nhueffme 2559 geometry = self.geom.GetGeometryRef(i)
151 nhueffme 2549 # if geometry object is polygon
152 nhueffme 2493 if geometry.GetGeometryCount() == 0:
153     for point in range(geometry.GetPointCount()):
154     x = geometry.GetX(point)
155     y = geometry.GetY(point)
156     points.append((x, y))
157     shape.append(points)
158 nhueffme 2577 # if geometry object is of type multipolygon or geometry collection
159 nhueffme 2549 else:
160 nhueffme 2493 for j in range(geometry.GetGeometryCount()):
161     points = []
162     subgeom = geometry.GetGeometryRef(j)
163     for point in range(subgeom.GetPointCount()):
164     x = subgeom.GetX(point)
165     y = subgeom.GetY(point)
166     points.append((x, y))
167     shape.append(points)
168     return shape
169 nhueffme 2435
170     def RawData(self):
171 nhueffme 2577 """Return the shape id to use with the shapestore
172     """
173 nhueffme 2435 return self.shapeid
174    
175     def OGRLayer(self):
176 nhueffme 2577 """Return the ogrlayer object
177     """
178 nhueffme 2435 return self.ogrlayer
179    
180 nhueffme 2559 def ShapeType(self):
181 nhueffme 2577 """Return the shapetype of this shape (may differ from the layer's
182     shapetype)
183     """
184 nhueffme 2559 return self.shapetype
185 nhueffme 2435
186 nhueffme 2577 def GetGeoms(self):
187     """Return the list of geometries of this feature.
188 nhueffme 2559
189 nhueffme 2577 If this feature is a geometry collection, all contained geometries
190     are given. Else the returned list is empty.
191     """
192     return self.geoms
193 nhueffme 2435
194 nhueffme 2577 def GetGeom(self, index):
195     """Return the OGRGeometry object at the specified index.
196    
197     This is not none only if the shape is a geometry collection.
198     """
199     if index < len(self.geoms):
200     return self.geoms[index]
201     else:
202     return None
203    
204    
205     class OGRGeometry:
206     """This class represents a geometry belonging to a specified feature.
207 nhueffme 2493 """
208 nhueffme 2435
209 nhueffme 2577 def __init__(self, shape, geom, index):
210     """Initialize the geometry object.
211 nhueffme 2435
212 nhueffme 2577 shape should be an OGRShape, which this geometry belongs to.
213     geom is the base geometry, index is the ReferenceID.
214     """
215     self.shape = shape
216     self.index = index
217    
218     self.geom = geom.GetGeometryRef(index)
219     try:
220     self.shapetype = ogrlib_shapetypes[self.geom.GetGeometryType()]
221     except:
222     self.shapetype = ogrlib_shapetypes[ogr.wkbUnknown]
223    
224    
225     def ShapeType(self):
226     """Return the shapetype of this geometry object."""
227     return self.shapetype
228    
229    
230     class OGRShapeStore:
231     """Corresponds to an OGRLayer object, containing features/shapes and
232     providing the same methods like ShapefileStore.
233 jan 2608
234     In fact, for all file based shape stores, the class OGRFileShapeStore
235     should be used. Only database shape stores should be
236     used with OGRShapeStore. It is subject to re-factoring
237     to end up with better class names and sensible base classes.
238 nhueffme 2577 """
239    
240 jan 2608 # TODO: re-factor this class to be not responsible for file-based
241     # stores anymore.
242    
243 nhueffme 2577 def __init__(self, session, filename, layername, id_column = None):
244     """Initialize the shapestore.
245    
246     All required information is loaded from the datasource.
247     """
248     # if id_column is None, data is loaded from file, so we need path
249     # if id_column is not None, data is loaded from database
250     if id_column is None:
251     self.filename = os.path.abspath(filename)
252     else:
253     self.filename = filename
254 nhueffme 2493 self.layername = layername
255 nhueffme 2435
256 nhueffme 2549 self.ogrdatasource = ogr.Open(filename)
257 nhueffme 2493 self.ogrlayer = (self.ogrdatasource).GetLayerByName(layername)
258 nhueffme 2435
259 nhueffme 2577 if id_column is not None:
260     self.id_column = id_column
261 nhueffme 2549 else:
262 nhueffme 2577 self.id_column = None
263 nhueffme 2549
264 nhueffme 2577 self.table = OGRTable(session, self.ogrdatasource, self.ogrlayer,
265     self.id_column)
266 nhueffme 2549
267 nhueffme 2435 self._open_ogrlayer(layername)
268    
269     def _open_ogrlayer(self, layername):
270 nhueffme 2577 """Get all required information from the datasource.
271     """
272 nhueffme 2493 self.numshapes = self.ogrlayer.GetFeatureCount()
273     self.shapetype = self.ogrlayer.GetLayerDefn().GetGeomType()
274 nhueffme 2549
275 nhueffme 2493 extent = self.ogrlayer.GetExtent()
276     if extent:
277     self.bbox = [extent[0], extent[2], extent[1], extent[3]]
278     else:
279     self.bbox = None
280 nhueffme 2435
281 nhueffme 2577 try:
282 nhueffme 2549 self.shapetype = ogrlib_shapetypes[self.shapetype]
283 nhueffme 2577 except:
284     # if shapetype is not contained in ogrlib_shapetypes
285     # treat it like SHAPETYPE_UNKNOWN
286     self.shapetype = ogrlib_shapetypes[ogr.wkbUnknown]
287 nhueffme 2435
288 nhueffme 2577 self.shapes = self.shapes()
289    
290     def shapes(self):
291     """Return a collection of all features as OGRShape objects.
292     """
293     shapes = {}
294     self.ogrlayer.ResetReading()
295     if self.id_column is None:
296     nextFeature = self.ogrlayer.GetNextFeature()
297     while nextFeature is not None:
298     fid = nextFeature.GetFID()
299     shape = OGRShape(self, nextFeature)
300     shapes[shape.ShapeID()] = shape
301     nextFeature = self.ogrlayer.GetNextFeature()
302     else:
303     lay = self.ogrdatasource.ExecuteSQL("SELECT %s, * from %s"
304     % (self.id_column, self.layername))
305     if lay is not None:
306     lay.ResetReading()
307     nextFeature = lay.GetNextFeature()
308     while nextFeature is not None:
309     fid = nextFeature.GetField(0)
310     shape = OGRShape(self, nextFeature)
311     shapes[shape.ShapeID()] = shape
312     nextFeature = lay.GetNextFeature()
313     self.ogrdatasource.ReleaseResultSet(lay)
314     return shapes
315    
316 nhueffme 2435 def OGRLayer(self):
317 nhueffme 2577 """Return the OGRLayer object
318     """
319 nhueffme 2435 return self.ogrlayer
320    
321     def FileName(self):
322 nhueffme 2577 """Return the filename used to open the file
323     """
324 nhueffme 2435 return self.filename
325    
326     def FileType(self):
327 nhueffme 2577 """Return the filetype. This is depending on the driver used to open
328     the file.
329     """
330     return self.ogrdatasource.GetDriver().GetName()
331 nhueffme 2435
332     def ShapeType(self):
333     """Return the type of the shapes in the shapestore.
334    
335 nhueffme 2577 This is either SHAPETYPE_POINT, SHAPETYPE_ARC, SHAPETYPE_POLYGON,
336     SHAEPTYPE_GEOMCOLL, SHAPETYPE_NONE or SHAPETYPE_UNKNOWN.
337 nhueffme 2435 """
338     return self.shapetype
339    
340     def RawShapeFormat(self):
341 nhueffme 2577 """Return the raw data format of the shape data, i.e. RAW_PYTHON
342     """
343 nhueffme 2493 return RAW_PYTHON
344 nhueffme 2435
345     def NumShapes(self):
346 nhueffme 2577 """Return the number of shapes in the shape store
347     """
348 nhueffme 2435 return self.numshapes
349    
350     def BoundingBox(self):
351     """Return the bounding box of the shapes in the shapestore.
352     """
353     return self.bbox
354    
355     def ShapesInRegion(self, bbox):
356     """Return an iterable over the shapes that overlap the bounding box.
357    
358     The bbox parameter should be the bounding box as a tuple in the
359     form (minx, miny, maxx, maxy) in the coordinate system of the
360     shape store.
361     """
362 nhueffme 2577 left, bottom, right, top = bbox
363 nhueffme 2435
364 nhueffme 2493 # create a geometry which can be passed to the layer as spatial filter
365     bboxpolygon = ogr.CreateGeometryFromWkt(
366     ('Polygon((%s %s, %s %s, %s %s,%s %s, %s %s))'
367 nhueffme 2577 %(left, bottom, left, top, right, top,
368 nhueffme 2493 right, bottom, left, bottom)))
369 nhueffme 2435
370 nhueffme 2577 if self.ogrlayer.GetSpatialRef():
371     bboxpolygon.AssignSpatialReference(self.ogrlayer.GetSpatialRef())
372 nhueffme 2435
373 nhueffme 2577 self.ogrlayer.ResetReading()
374 nhueffme 2549 #ogrlayer.SetSpatialFilterRect(left, bottom, right, top)
375 nhueffme 2577 self.ogrlayer.SetSpatialFilter(bboxpolygon)
376 nhueffme 2559
377 nhueffme 2577 numFeatures = self.ogrlayer.GetFeatureCount()
378     # if no features are in bbox, return all features as shapesInRegion
379     # (PostGIS sometimes returns no features even if they are within
380     # the bounding box)
381     if numFeatures == 0:
382     self.ogrlayer.SetSpatialFilter(None)
383     numFeatures = self.ogrlayer.GetFeatureCount()
384 nhueffme 2493 for feature in range(numFeatures):
385 nhueffme 2577 nextFeature = self.ogrlayer.GetNextFeature()
386     if self.id_column is None:
387     yield self.shapes[nextFeature.GetFID()]
388     else:
389     yield self.shapes[nextFeature.GetField(self.id_column)]
390 nhueffme 2559
391 nhueffme 2577 self.ogrlayer.SetSpatialFilter(None)
392 nhueffme 2493 bboxpolygon.Destroy()
393 nhueffme 2435
394     def AllShapes(self):
395 nhueffme 2577 """Return an iterable over the shapes in the shape store.
396     """
397     for id in range(len(self.shapes)):
398     yield self.shapes[id]
399 nhueffme 2435
400 nhueffme 2577 def Shape(self, fid):
401     """Return the shape with fid = fid
402     """
403     if fid in self.table.ids.keys():
404     return self.shapes[fid]
405     else:
406     return None
407 nhueffme 2435
408     def Table(self):
409 nhueffme 2577 """Return the table containing the attribute data
410     """
411 nhueffme 2435 return self.table
412    
413     def Dependencies(self):
414 nhueffme 2577 """Return the empty tuple.
415     """
416 nhueffme 2435 return ()
417    
418     def OrigShapeStore(self):
419     """Return None."""
420     return None
421    
422 nhueffme 2559 def Id_column(self):
423 nhueffme 2577 """Return the id_column.
424     """
425 nhueffme 2559 return self.id_column
426 nhueffme 2435
427 jan 2608 class OGRFileShapeStore(FileShapeStore):
428     """Corresponds to an OGRLayer object, containing features/shapes and
429     providing the same methods like ShapefileStore.
430     """
431    
432     def __init__(self, session, filename, layername, id_column = None):
433     """Initialize the shapestore.
434    
435     All required information is loaded from the datasource.
436     """
437     self._bbox = None
438     self.ogrdatasource = ogr.Open(filename)
439    
440     # filetype is depending on the driver used to open the file.
441     self._filetype = self.ogrdatasource.GetDriver().GetName()
442     if self._filetype == 'ESRI Shapefile':
443     self._filetype = "shapefile"
444     FileShapeStore.__init__(self, filename,
445     sublayer_name = layername)
446    
447     self.ogrlayer = (self.ogrdatasource).GetLayerByName(layername)
448    
449     self._table = OGRTable(session, self.ogrdatasource, self.ogrlayer,
450     id_column)
451    
452     self._open_ogrlayer(layername)
453    
454     def _open_ogrlayer(self, layername):
455     """Get all required information from the datasource.
456     """
457     self.numshapes = self.ogrlayer.GetFeatureCount()
458     self.shapetype = self.ogrlayer.GetLayerDefn().GetGeomType()
459    
460     extent = self.ogrlayer.GetExtent()
461     if extent:
462     self._bbox = [extent[0], extent[2], extent[1], extent[3]]
463     else:
464     self._bbox = None
465    
466     try:
467     self.shapetype = ogrlib_shapetypes[self.shapetype]
468     except:
469     # if shapetype is not contained in ogrlib_shapetypes
470     # treat it like SHAPETYPE_UNKNOWN
471     self.shapetype = ogrlib_shapetypes[ogr.wkbUnknown]
472    
473     self.shapes = self.shapes()
474    
475     def FileType(self):
476     """Return the filetype."""
477     return self._filetype
478    
479     def BoundingBox(self):
480     """Return the bounding box of the shapes in the shape file.
481    
482     The coordinate system used is whatever was used in the shape file.
483     If the shape file is empty, return None.
484     """
485     return self._bbox
486    
487     def shapes(self):
488     """Return a collection of all features as OGRShape objects.
489     """
490     shapes = {}
491     self.ogrlayer.ResetReading()
492    
493     nextFeature = self.ogrlayer.GetNextFeature()
494     while nextFeature is not None:
495     fid = nextFeature.GetFID()
496     shape = OGRShape(self, nextFeature)
497     shapes[shape.ShapeID()] = shape
498     nextFeature = self.ogrlayer.GetNextFeature()
499    
500     return shapes
501    
502     def OGRLayer(self):
503     """Return the OGRLayer object
504     """
505     return self.ogrlayer
506    
507     def ShapeType(self):
508     """Return the type of the shapes in the shapestore.
509    
510     This is either SHAPETYPE_POINT, SHAPETYPE_ARC, SHAPETYPE_POLYGON,
511     SHAEPTYPE_GEOMCOLL, SHAPETYPE_NONE or SHAPETYPE_UNKNOWN.
512     """
513     return self.shapetype
514    
515     def RawShapeFormat(self):
516     """Return the raw data format of the shape data, i.e. RAW_PYTHON
517     """
518     return RAW_PYTHON
519    
520     def NumShapes(self):
521     """Return the number of shapes in the shape store
522     """
523     return self.numshapes
524    
525     def ShapesInRegion(self, bbox):
526     """Return an iterable over the shapes that overlap the bounding box.
527    
528     The bbox parameter should be the bounding box as a tuple in the
529     form (minx, miny, maxx, maxy) in the coordinate system of the
530     shape store.
531     """
532     left, bottom, right, top = bbox
533    
534     # create a geometry which can be passed to the layer as spatial filter
535     bboxpolygon = ogr.CreateGeometryFromWkt(
536     ('Polygon((%s %s, %s %s, %s %s,%s %s, %s %s))'
537     %(left, bottom, left, top, right, top,
538     right, bottom, left, bottom)))
539    
540     if self.ogrlayer.GetSpatialRef():
541     bboxpolygon.AssignSpatialReference(self.ogrlayer.GetSpatialRef())
542    
543     self.ogrlayer.ResetReading()
544     #ogrlayer.SetSpatialFilterRect(left, bottom, right, top)
545     self.ogrlayer.SetSpatialFilter(bboxpolygon)
546    
547     numFeatures = self.ogrlayer.GetFeatureCount()
548     # if no features are in bbox, return all features as shapesInRegion
549     # (PostGIS sometimes returns no features even if they are within
550     # the bounding box)
551     if numFeatures == 0:
552     self.ogrlayer.SetSpatialFilter(None)
553     numFeatures = self.ogrlayer.GetFeatureCount()
554     for feature in range(numFeatures):
555     nextFeature = self.ogrlayer.GetNextFeature()
556     yield self.shapes[nextFeature.GetFID()]
557    
558     self.ogrlayer.SetSpatialFilter(None)
559     bboxpolygon.Destroy()
560    
561     def AllShapes(self):
562     """Return an iterable over the shapes in the shape store.
563     """
564     for id in range(len(self.shapes)):
565     yield self.shapes[id]
566    
567     def Shape(self, fid):
568     """Return the shape with fid = fid
569     """
570     if fid in self.Table().ids.keys():
571     return self.shapes[fid]
572     else:
573     return None
574    
575     def Table(self):
576     """Return the table containing the attribute data."""
577     return self._table
578    
579     def Dependencies(self):
580     """Return the empty tuple.
581     """
582     return ()
583    
584     def OrigShapeStore(self):
585     """Return None."""
586     return None
587    
588     def Id_column(self):
589     """Return the id_column.
590     """
591     return None
592    
593 nhueffme 2577 class OGRTable(transientdb.AutoTransientTable):
594     """A Table for an ogr datasource.
595 nhueffme 2435 """
596    
597 nhueffme 2577 def __init__(self, session, ds, layer, id_column):
598 nhueffme 2435 """Initialize the OGRTable.
599    
600 nhueffme 2577 session - should be the current session.
601     ds - should be an instance of OGRDatasource.
602     layer - should be an instance of OGRLayer.
603     id_column - should be the name of the column used as ID column
604 nhueffme 2435 """
605     self.datasource = ds
606     self.layer = layer
607 nhueffme 2577 self.tablename = self.layer.GetName()
608 nhueffme 2549 self.id_column = id_column
609 nhueffme 2435
610     # Map column names and indices to column objects.
611     self.column_map = {}
612    
613 nhueffme 2549 # Map feature ids to ordinals.
614     self._map_ords_and_ids()
615    
616 nhueffme 2435 self._fetch_table_information()
617 nhueffme 2577 self._fetch_table_content()
618 nhueffme 2435
619 nhueffme 2577 transientdb.AutoTransientTable.__init__(self, session.TransientDB(),
620     self)
621    
622 nhueffme 2435 def _fetch_table_information(self):
623 nhueffme 2577 """Internal: Update information about the table
624     """
625 nhueffme 2435 self.columns = []
626    
627 nhueffme 2493 layerdefn = self.layer.GetLayerDefn()
628 nhueffme 2577 # if FID column is of interest
629     #col = OGRColumn("FID", table.FIELDTYPE_INT, layerdefn.GetFieldCount())
630     #self.columns.append(col)
631 nhueffme 2493 for i in range(layerdefn.GetFieldCount()):
632     fielddef = layerdefn.GetFieldDefn(i)
633     fieldname = fielddef.GetName()
634     fieldtype = fieldtype_map[fielddef.GetType()]
635     fieldindex = layerdefn.GetFieldIndex(fieldname)
636     col = OGRColumn(fieldname, fieldtype, fieldindex)
637     if col is not None:
638     self.columns.append(col)
639 nhueffme 2435
640     for col in self.columns:
641     self.column_map[col.name] = col
642     self.column_map[col.index] = col
643    
644 nhueffme 2577 def _fetch_table_content(self):
645     """Internal: Update information contained in the table
646     """
647     self.content = []
648     layerdefn = self.layer.GetLayerDefn()
649    
650     self.layer.ResetReading()
651     for i in range(self.layer.GetFeatureCount()):
652     nextFeature = self.layer.GetNextFeature()
653     row = []
654     for j in range(layerdefn.GetFieldCount()):
655     row.append(nextFeature.GetField(j))
656     # if FID should be listed in the table
657     #if self.id_column is None:
658     # row.append(nextFeature.GetFID())
659     #else:
660     # row.append(nextFeature.GetField(self.id_column))
661     self.content.append(row)
662    
663 nhueffme 2549 def _map_ords_and_ids(self):
664 nhueffme 2577 """Create collections which map ordinals to ids and verse visa.
665     """
666 nhueffme 2549 self.ordinals = {}
667     self.ids = {}
668    
669 nhueffme 2577 if self.id_column is not None:
670     lay = self.datasource.ExecuteSQL("SELECT %s from %s"
671     %(self.id_column, self.tablename))
672     lay.ResetReading()
673     nextFeature = lay.GetNextFeature()
674     else:
675     self.layer.ResetReading()
676     nextFeature = self.layer.GetNextFeature()
677    
678 nhueffme 2549 ord = 0
679     while nextFeature is not None:
680 nhueffme 2577 if self.id_column is not None:
681     id = nextFeature.GetField(self.id_column)
682     nextFeature = lay.GetNextFeature()
683     else:
684     id = nextFeature.GetFID()
685     nextFeature = self.layer.GetNextFeature()
686 nhueffme 2549 self.ordinals[ord] = id
687     self.ids[id] = ord
688     ord = ord + 1
689 nhueffme 2577 if self.id_column is not None:
690     self.datasource.ReleaseResultSet(lay)
691 nhueffme 2549
692 nhueffme 2435 def TableName(self):
693 nhueffme 2577 """Return the name of the table, which is the name of the layer
694     """
695 nhueffme 2435 return self.tablename
696    
697     def Title(self):
698     """Return the title of the table.
699     """
700     return self.tablename
701    
702     def Dependencies(self):
703 nhueffme 2577 """Return an empty tuple.
704     """
705 nhueffme 2435 return ()
706    
707     def NumColumns(self):
708 nhueffme 2577 """Return the number of columns.
709     """
710 nhueffme 2435 return len(self.columns)
711    
712     def Columns(self):
713 nhueffme 2577 """Return all columns.
714     """
715 nhueffme 2435 return self.columns
716    
717     def Column(self, col):
718 nhueffme 2577 """Return the column col. col can be either a string or an integer.
719     """
720 nhueffme 2435 return self.column_map[col]
721    
722     def HasColumn(self, col):
723 nhueffme 2577 """Return if column col exists. col can be either a string or an
724 nhueffme 2493 integer.
725     """
726 nhueffme 2435 return self.column_map.has_key(col)
727    
728     def NumRows(self):
729 nhueffme 2577 """Return the number of rows in the table, which equals the number of
730 nhueffme 2493 features in the layer.
731     """
732 nhueffme 2577 return len(self.ids)
733 nhueffme 2435
734     def RowIdToOrdinal(self, gid):
735 nhueffme 2577 """Return the row ordinal given its id
736     """
737 nhueffme 2549 if gid < 0:
738     return gid
739     else:
740     ord = self.ids[gid]
741     return ord
742 nhueffme 2435
743     def RowOrdinalToId(self, num):
744 nhueffme 2577 """Return the rowid for given its ordinal
745     """
746 nhueffme 2549 if num >= 0:
747     id = self.ordinals[num]
748     return id
749     else:
750     return num
751 nhueffme 2435
752     def ReadRowAsDict(self, row, row_is_ordinal = 0):
753 nhueffme 2577 """Return a dictionary which contains all the fields.
754     """
755     if row_is_ordinal == 0:
756     rowId = self.RowIdToOrdinal(row)
757 nhueffme 2549 else:
758     rowId = row
759 nhueffme 2493 result = {}
760 nhueffme 2577 for i in range(self.NumColumns()):
761     result[self.Column(i).name] = self.content[rowId][i]
762 nhueffme 2435 return result
763    
764     def ReadValue(self, row, col, row_is_ordinal = 0):
765 nhueffme 2577 """Return the requested value.
766     """
767     if row_is_ordinal == 0:
768     rowId = self.RowIdToOrdinal(row)
769 nhueffme 2493 else:
770 nhueffme 2577 rowId = row
771     colIndex = self.column_map[col].index
772     return self.content[rowId][colIndex]
773 nhueffme 2435
774     def ValueRange(self, col):
775 nhueffme 2577 """Return the value range of the given column (given as string).
776     """
777    
778 nhueffme 2493 result = self.datasource.ExecuteSQL("SELECT min(%s), max(%s) FROM %s"
779     %(col, col, self.layer.GetName()))
780     result.ResetReading()
781     feature = result.GetNextFeature()
782     try:
783     min = feature.GetField(0)
784     max = feature.GetField(1)
785     except:
786     min = 0
787     max = 0
788     self.datasource.ReleaseResultSet(result)
789 nhueffme 2435 return (min, max)
790    
791     def UniqueValues(self, col):
792 nhueffme 2493 """Return all the values being found in the column (given as string).
793     """
794     result = self.datasource.ExecuteSQL((
795     "SELECT DISTINCT %s FROM %s ORDER BY %s"
796     %(col,self.layer.GetName(),col)))
797     values = []
798     while 1:
799     feature = result.GetNextFeature()
800     if feature is None:
801     break
802     values.append(feature.GetField(0))
803     self.datasource.ReleaseResultSet(result)
804 nhueffme 2435 return values
805    
806     def SimpleQuery(self, left, comparison, right):
807 nhueffme 2577 """Return the FIDs resulting from the given query.
808     """
809    
810 nhueffme 2435 if comparison not in ("==", "!=", "<", "<=", ">=", ">"):
811 nhueffme 2493 raise ValueError("Comparison operator %r not allowed" %comparison)
812 nhueffme 2435
813     if comparison == "==":
814     comparison = "="
815    
816     if isinstance(right, OGRColumn):
817     right_template = right.name
818     else:
819     right_template = right
820    
821 nhueffme 2577 if self.id_column is None:
822     id = "FID"
823     else:
824     id = self.id_column
825     query = ("SELECT %s FROM %s WHERE %s %s %s ORDER BY %s"
826     % (id, self.tablename,left.name, comparison,
827     right_template, id))
828 nhueffme 2435
829     lay = self.datasource.ExecuteSQL(query)
830 nhueffme 2493 result = []
831     while lay is not None:
832 nhueffme 2435 feature = lay.GetNextFeature()
833     if feature is None:
834     break
835     result.append(feature.GetField(0))
836 nhueffme 2549 if lay is not None:
837     self.datasource.ReleaseResultSet(lay)
838 nhueffme 2435 return result
839    
840 nhueffme 2559 def Id_column(self):
841 nhueffme 2577 """Return the id_column.
842     """
843 nhueffme 2559 return self.id_column
844 nhueffme 2435
845 nhueffme 2559
846 nhueffme 2435 class OGRColumn:
847     """Column description for a table for an ogr file
848     """
849    
850     def __init__(self, name, type, index):
851     self.name = name
852     self.type = type
853     self.index = index

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26