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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2734 - (show annotations)
Thu Mar 1 12:42:59 2007 UTC (18 years ago) by bramz
File MIME type: text/x-python
File size: 27513 byte(s)
made a copy
1 # Copyright (C) 2004 by Intevation GmbH vim:encoding=latin-1:
2 # Authors:
3 # Nina Hüffmeyer <[email protected]>
4 #
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 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
27 from Thuban.Model.data import RAW_PYTHON, RAW_SHAPEFILE, RAW_WKT
28 from Thuban.Model.data import FileShapeStore
29
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 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 ogrlib_shapetypes = {ogr.wkbPolygon: SHAPETYPE_POLYGON,
45 ogr.wkbLineString: SHAPETYPE_ARC,
46 ogr.wkbPoint: SHAPETYPE_POINT,
47 ogr.wkbUnknown: SHAPETYPE_UNKNOWN,
48 ogr.wkbNone: SHAPETYPE_NONE,
49 ogr.wkbGeometryCollection: SHAPETYPE_GEOMCOLL}
50
51 fieldtype_map = {ogr.OFTString: table.FIELDTYPE_STRING,
52 ogr.OFTInteger: table.FIELDTYPE_INT,
53 ogr.OFTReal: table.FIELDTYPE_DOUBLE}
54
55 else:
56 ogrlib_shapetypes = {}
57 fieldtype_map = {}
58 SHAPETYPE_UNKNOWN = 0
59 SHAPETYPE_GEOMCOLL = 7
60 SHAPETYPE_NONE = 100
61
62
63 class OGRShape:
64 """Represent one shape of an OGRShapeStore
65 """
66
67 def __init__(self, shapestore, shape):
68 """Initialize the shape object.
69
70 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 self.geom = self.feature.GetGeometryRef()
81 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
94 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 """
102 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 """
110 Compute the bounding box of the shape as a tuple (minx,miny,maxx,maxy)
111 """
112 minx, maxx, miny, maxy = self.geom.GetEnvelope()
113 return (minx, miny, maxx, maxy)
114
115 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 def ShapeID(self):
122 """Return the feature id of this shape.
123 """
124 return self.shapeid
125
126 def Points(self):
127 """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 shape = []
135
136 if self.geom is None:
137 return shape.append([])
138
139 # if geometry object is of type point or line
140 if self.geom.GetGeometryCount() == 0:
141 points =[]
142 for point in range(self.geom.GetPointCount()):
143 x = self.geom.GetX(point)
144 y = self.geom.GetY(point)
145 points.append((x, y))
146 return [points]
147 # if geometry object is of type polygon or multipolygon
148 for i in range(self.geom.GetGeometryCount()):
149 points = []
150 geometry = self.geom.GetGeometryRef(i)
151 # if geometry object is polygon
152 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 # if geometry object is of type multipolygon or geometry collection
159 else:
160 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
170 def RawData(self):
171 """Return the shape id to use with the shapestore
172 """
173 return self.shapeid
174
175 def OGRLayer(self):
176 """Return the ogrlayer object
177 """
178 return self.ogrlayer
179
180 def ShapeType(self):
181 """Return the shapetype of this shape (may differ from the layer's
182 shapetype)
183 """
184 return self.shapetype
185
186 def GetGeoms(self):
187 """Return the list of geometries of this feature.
188
189 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
194 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 """
208
209 def __init__(self, shape, geom, index):
210 """Initialize the geometry object.
211
212 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
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 """
239
240 # TODO: re-factor this class to be not responsible for file-based
241 # stores anymore.
242
243 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 self.layername = layername
255
256 self.ogrdatasource = ogr.Open(filename)
257 self.ogrlayer = (self.ogrdatasource).GetLayerByName(layername)
258
259 if id_column is not None:
260 self.id_column = id_column
261 else:
262 self.id_column = None
263
264 self.table = OGRTable(session, self.ogrdatasource, self.ogrlayer,
265 self.id_column)
266
267 self._open_ogrlayer(layername)
268
269 def _open_ogrlayer(self, layername):
270 """Get all required information from the datasource.
271 """
272 self.numshapes = self.ogrlayer.GetFeatureCount()
273 self.shapetype = self.ogrlayer.GetLayerDefn().GetGeomType()
274
275 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
281 try:
282 self.shapetype = ogrlib_shapetypes[self.shapetype]
283 except:
284 # if shapetype is not contained in ogrlib_shapetypes
285 # treat it like SHAPETYPE_UNKNOWN
286 self.shapetype = ogrlib_shapetypes[ogr.wkbUnknown]
287
288 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 def OGRLayer(self):
317 """Return the OGRLayer object
318 """
319 return self.ogrlayer
320
321 def FileName(self):
322 """Return the filename used to open the file
323 """
324 return self.filename
325
326 def FileType(self):
327 """Return the filetype. This is depending on the driver used to open
328 the file.
329 """
330 return self.ogrdatasource.GetDriver().GetName()
331
332 def ShapeType(self):
333 """Return the type of the shapes in the shapestore.
334
335 This is either SHAPETYPE_POINT, SHAPETYPE_ARC, SHAPETYPE_POLYGON,
336 SHAEPTYPE_GEOMCOLL, SHAPETYPE_NONE or SHAPETYPE_UNKNOWN.
337 """
338 return self.shapetype
339
340 def RawShapeFormat(self):
341 """Return the raw data format of the shape data, i.e. RAW_PYTHON
342 """
343 return RAW_PYTHON
344
345 def NumShapes(self):
346 """Return the number of shapes in the shape store
347 """
348 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 left, bottom, right, top = bbox
363
364 # 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 %(left, bottom, left, top, right, top,
368 right, bottom, left, bottom)))
369
370 if self.ogrlayer.GetSpatialRef():
371 bboxpolygon.AssignSpatialReference(self.ogrlayer.GetSpatialRef())
372
373 self.ogrlayer.ResetReading()
374 #ogrlayer.SetSpatialFilterRect(left, bottom, right, top)
375 self.ogrlayer.SetSpatialFilter(bboxpolygon)
376
377 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 for feature in range(numFeatures):
385 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
391 self.ogrlayer.SetSpatialFilter(None)
392 bboxpolygon.Destroy()
393
394 def AllShapes(self):
395 """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
400 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
408 def Table(self):
409 """Return the table containing the attribute data
410 """
411 return self.table
412
413 def Dependencies(self):
414 """Return the empty tuple.
415 """
416 return ()
417
418 def OrigShapeStore(self):
419 """Return None."""
420 return None
421
422 def Id_column(self):
423 """Return the id_column.
424 """
425 return self.id_column
426
427 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 class OGRTable(transientdb.AutoTransientTable):
594 """A Table for an ogr datasource.
595 """
596
597 def __init__(self, session, ds, layer, id_column):
598 """Initialize the OGRTable.
599
600 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 """
605 self.datasource = ds
606 self.layer = layer
607 self.tablename = self.layer.GetName()
608 self.id_column = id_column
609
610 # Map column names and indices to column objects.
611 self.column_map = {}
612
613 # Map feature ids to ordinals.
614 self._map_ords_and_ids()
615
616 self._fetch_table_information()
617 self._fetch_table_content()
618
619 transientdb.AutoTransientTable.__init__(self, session.TransientDB(),
620 self)
621
622 def _fetch_table_information(self):
623 """Internal: Update information about the table
624 """
625 self.columns = []
626
627 layerdefn = self.layer.GetLayerDefn()
628 # if FID column is of interest
629 #col = OGRColumn("FID", table.FIELDTYPE_INT, layerdefn.GetFieldCount())
630 #self.columns.append(col)
631 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
640 for col in self.columns:
641 self.column_map[col.name] = col
642 self.column_map[col.index] = col
643
644 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 def _map_ords_and_ids(self):
664 """Create collections which map ordinals to ids and verse visa.
665 """
666 self.ordinals = {}
667 self.ids = {}
668
669 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 ord = 0
679 while nextFeature is not None:
680 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 self.ordinals[ord] = id
687 self.ids[id] = ord
688 ord = ord + 1
689 if self.id_column is not None:
690 self.datasource.ReleaseResultSet(lay)
691
692 def TableName(self):
693 """Return the name of the table, which is the name of the layer
694 """
695 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 """Return an empty tuple.
704 """
705 return ()
706
707 def NumColumns(self):
708 """Return the number of columns.
709 """
710 return len(self.columns)
711
712 def Columns(self):
713 """Return all columns.
714 """
715 return self.columns
716
717 def Column(self, col):
718 """Return the column col. col can be either a string or an integer.
719 """
720 return self.column_map[col]
721
722 def HasColumn(self, col):
723 """Return if column col exists. col can be either a string or an
724 integer.
725 """
726 return self.column_map.has_key(col)
727
728 def NumRows(self):
729 """Return the number of rows in the table, which equals the number of
730 features in the layer.
731 """
732 return len(self.ids)
733
734 def RowIdToOrdinal(self, gid):
735 """Return the row ordinal given its id
736 """
737 if gid < 0:
738 return gid
739 else:
740 ord = self.ids[gid]
741 return ord
742
743 def RowOrdinalToId(self, num):
744 """Return the rowid for given its ordinal
745 """
746 if num >= 0:
747 id = self.ordinals[num]
748 return id
749 else:
750 return num
751
752 def ReadRowAsDict(self, row, row_is_ordinal = 0):
753 """Return a dictionary which contains all the fields.
754 """
755 if row_is_ordinal == 0:
756 rowId = self.RowIdToOrdinal(row)
757 else:
758 rowId = row
759 result = {}
760 for i in range(self.NumColumns()):
761 result[self.Column(i).name] = self.content[rowId][i]
762 return result
763
764 def ReadValue(self, row, col, row_is_ordinal = 0):
765 """Return the requested value.
766 """
767 if row_is_ordinal == 0:
768 rowId = self.RowIdToOrdinal(row)
769 else:
770 rowId = row
771 colIndex = self.column_map[col].index
772 return self.content[rowId][colIndex]
773
774 def ValueRange(self, col):
775 """Return the value range of the given column (given as string).
776 """
777
778 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 return (min, max)
790
791 def UniqueValues(self, col):
792 """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 return values
805
806 def SimpleQuery(self, left, comparison, right):
807 """Return the FIDs resulting from the given query.
808 """
809
810 if comparison not in ("==", "!=", "<", "<=", ">=", ">"):
811 raise ValueError("Comparison operator %r not allowed" %comparison)
812
813 if comparison == "==":
814 comparison = "="
815
816 if isinstance(right, OGRColumn):
817 right_template = right.name
818 else:
819 right_template = right
820
821 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
829 lay = self.datasource.ExecuteSQL(query)
830 result = []
831 while lay is not None:
832 feature = lay.GetNextFeature()
833 if feature is None:
834 break
835 result.append(feature.GetField(0))
836 if lay is not None:
837 self.datasource.ReleaseResultSet(lay)
838 return result
839
840 def Id_column(self):
841 """Return the id_column.
842 """
843 return self.id_column
844
845
846 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