/[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 2549 by nhueffme, Wed Jan 26 09:17:01 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 26  from Thuban.Model import table Line 26  from Thuban.Model import table
26  from Thuban.Model.data import SHAPETYPE_POLYGON, SHAPETYPE_ARC, SHAPETYPE_POINT  from Thuban.Model.data import SHAPETYPE_POLYGON, SHAPETYPE_ARC, SHAPETYPE_POINT
27  from Thuban.Model.data import RAW_PYTHON, RAW_SHAPEFILE, RAW_WKT  from Thuban.Model.data import RAW_PYTHON, RAW_SHAPEFILE, RAW_WKT
28    
29  # Raw data in ogr format  SHAPETYPE_UNKNOWN = "unknown"
 RAW_OGRSHAPES = "RAW_OGRSHAPES"  
   
   
30    
31  def has_ogr_support():  def has_ogr_support():
32      """Return whether this Thuban instance supports ogr file formats      """Return whether this Thuban instance supports ogr file formats
# Line 42  def has_ogr_support(): Line 39  def has_ogr_support():
39  if ogr is not None:  if ogr is not None:
40      # mapping from ogr-lib shapetype and table constants to our constants      # mapping from ogr-lib shapetype and table constants to our constants
41      ogrlib_shapetypes = {ogr.wkbPolygon: SHAPETYPE_POLYGON,      ogrlib_shapetypes = {ogr.wkbPolygon: SHAPETYPE_POLYGON,
42                         ogr.wkbLineString: SHAPETYPE_ARC,                  ogr.wkbLineString: SHAPETYPE_ARC,
43                         ogr.wkbPoint: SHAPETYPE_POINT}                  ogr.wkbPoint: SHAPETYPE_POINT,
44                    ogr.wkbUnknown: SHAPETYPE_UNKNOWN}
45    
46      fieldtype_map = {ogr.OFTString: table.FIELDTYPE_STRING,      fieldtype_map = {ogr.OFTString: table.FIELDTYPE_STRING,
47          ogr.OFTInteger: table.FIELDTYPE_INT,                  ogr.OFTInteger: table.FIELDTYPE_INT,
48          ogr.OFTReal: table.FIELDTYPE_DOUBLE}                  ogr.OFTReal: table.FIELDTYPE_DOUBLE}
49    
50    
51  class OGRShape:  class OGRShape:
# Line 62  class OGRShape: Line 60  class OGRShape:
60          """          """
61          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)
62          """          """
63          shape = self.ogrlayer.GetFeature(self.shapeid)          shape = self.ogrlayer.GetFeature(self.shapeid)
64          geom = shape.GetGeometryRef()          geom = shape.GetGeometryRef()
65          minx, maxx, miny, maxy = geom.GetEnvelope()          minx, maxx, miny, maxy = geom.GetEnvelope()
66          return (minx, miny, maxx, maxy)          return (minx, miny, maxx, maxy)
67    
68      def ShapeID(self):      def ShapeID(self):
69          return self.shapeid          return self.shapeid
70    
     # 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().----------------------------  
71      def Points(self):      def Points(self):
72          """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"""
73            print "FID: %s" %(self.shapeid)
74            shape = []
75            #spatialFilter = self.ogrlayer.GetSpatialFilter()
76            
77    #        if spatialFilter is not None:
78            self.ogrlayer.SetSpatialFilter(None)
79      #          feature = self.ogrlayer.GetFeature(self.shapeid)
80       #         self.ogrlayer.SetSpatialFilter(spatialFilter)
81        #    else:
82          feature = self.ogrlayer.GetFeature(self.shapeid)          feature = self.ogrlayer.GetFeature(self.shapeid)
83          geometry = feature.GetGeometryRef()        
84          while geometry.GetGeometryCount() != 0:          if feature is None:
85                  geometry = geometry.GetGeometryRef(0)              print "feature is none.........................."
86          points = []              return shape.append([])
87          for point in range(geometry.GetPointCount()):          geom = feature.GetGeometryRef()
88                  x = geometry.GetX(point)  
89                  y = geometry.GetY(point)          if geom is None:
90                  points.append((x, y))              print "geom is none................................"
91          points = [points]              return shape.append([])
92          return points  
93            # if geometry object is of type point or line
94            if geom.GetGeometryCount() == 0:
95                points =[]
96                for point in range(geom.GetPointCount()):
97                    x = geom.GetX(point)
98                    y = geom.GetY(point)
99                    points.append((x, y))
100                print points
101                return [points]
102            # if geometry object is of type polygon or multipolygon
103            for i in range(geom.GetGeometryCount()):
104                points = []
105                geometry = geom.GetGeometryRef(i)
106                # if geometry object is polygon
107                if geometry.GetGeometryCount() == 0:
108                    for point in range(geometry.GetPointCount()):
109                        x = geometry.GetX(point)
110                        y = geometry.GetY(point)
111                        points.append((x, y))
112                    shape.append(points)
113                # if geometry object is of type multipolygon
114                else:
115                    for j in range(geometry.GetGeometryCount()):
116                        points = []
117                        subgeom = geometry.GetGeometryRef(j)
118                        for point in range(subgeom.GetPointCount()):
119                            x = subgeom.GetX(point)
120                            y = subgeom.GetY(point)
121                            points.append((x, y))
122                        shape.append(points)
123            print shape
124            return shape
125    
126      def RawData(self):      def RawData(self):
127          """Return the shape id to use with the shapestore"""          """Return the shape id to use with the shapestore"""
# Line 98  class OGRShape: Line 134  class OGRShape:
134    
135  class OGRShapeStore:  class OGRShapeStore:
136    
137      """Corresponds to an OGRLayer object, containing features/shapes and providing all methods Thuban      """Corresponds to an OGRLayer object, containing features/shapes and
138         needs."""         providing all methods Thuban needs.
139        """
140    
141      def __init__(self, session, filename, layername):      def __init__(self, session, filename, layername):
142          # Make the filename absolute. The filename will be          # Make the filename absolute. The filename will be
# Line 107  class OGRShapeStore: Line 144  class OGRShapeStore:
144          # session we need to compare absolute paths and it's usually          # session we need to compare absolute paths and it's usually
145          # safer to always work with absolute paths.          # safer to always work with absolute paths.
146    
147          self.filename = os.path.abspath(filename)          self.filename = filename
148          self.layername = layername          self.layername = layername
149    
150            self.ogrdatasource = ogr.Open(filename)
151            self.ogrlayer = (self.ogrdatasource).GetLayerByName(layername)
152    
153            driver = self.ogrdatasource.GetDriver().GetName()
154            if driver == 'PostgreSQL':
155                self.id_column = 'gid'
156            else:
157                self.id_column = 'fid'
158    
159          self.ogrdatasource = ogr.Open(self.filename)          self.table = OGRTable(self.ogrdatasource, self.ogrlayer, self.id_column)
         self.ogrlayer = (self.ogrdatasource).GetLayerByName(layername)  
         self.table = OGRTable(self.ogrdatasource, self.ogrlayer)  
160    
161          self._open_ogrlayer(layername)          self._open_ogrlayer(layername)
162    
163      def _open_ogrlayer(self, layername):      def _open_ogrlayer(self, layername):
164          self.numshapes = self.ogrlayer.GetFeatureCount()          self.numshapes = self.ogrlayer.GetFeatureCount()
165          self.shapetype = self.ogrlayer.GetLayerDefn().GetGeomType()          self.shapetype = self.ogrlayer.GetLayerDefn().GetGeomType()
         extent = self.ogrlayer.GetExtent()  
   
         if extent:  
                 self.bbox = [extent[0], extent[2], extent[1], extent[3]]  
         else:  
                 self.bbox = None  
166    
167          self.shapetype = ogrlib_shapetypes[self.shapetype]          extent = self.ogrlayer.GetExtent()
168            if extent:
169                self.bbox = [extent[0], extent[2], extent[1], extent[3]]
170            else:
171                self.bbox = None
172    
173            if self.shapetype is not ogr.wkbUnknown:
174                self.shapetype = ogrlib_shapetypes[self.shapetype]
175            #else:
176                # this should be ogr.wkbUnknown, but Thuban does not know how
177                # to handle an unknown shapetype (e.g. Session Tree)
178                #self.shapetype = ogrlib_shapetypes[ogr.wkbPoint]
179    
180      def OGRLayer(self):      def OGRLayer(self):
181          """Return the OGRLayer object"""          """Return the OGRLayer object"""
# Line 148  class OGRShapeStore: Line 197  class OGRShapeStore:
197          return self.shapetype          return self.shapetype
198    
199      def RawShapeFormat(self):      def RawShapeFormat(self):
200          """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"""
201          return RAW_OGRSHAPES          return RAW_PYTHON
202    
203      def NumShapes(self):      def NumShapes(self):
204          """Return the number of shapes in the shape store"""          """Return the number of shapes in the shape store"""
# Line 167  class OGRShapeStore: Line 216  class OGRShapeStore:
216          form (minx, miny, maxx, maxy) in the coordinate system of the          form (minx, miny, maxx, maxy) in the coordinate system of the
217          shape store.          shape store.
218    
219          The method GetFID() returns feature IDs starting from 0. In Thuban feature IDs start with 1.          The method GetFID() returns feature IDs starting from 0.
220          """          """
221          # Bind a few globals to locals to make it a bit faster          # Bind a few globals to locals to make it a bit faster
222          cls = OGRShape          cls = OGRShape
223          ogrlayer = self.ogrlayer          ogrlayer = self.ogrlayer
224    
225          left, bottom, right, top = bbox          left, bottom, right, top = bbox
226            print "features in bbox: "
227          # create a geometry which can be passed to the layer as spatial filter          print ('Polygon((%s %s, %s %s, %s %s,%s %s, %s %s))'
228          bboxpolygon = ogr.CreateGeometryFromWkt('Polygon((%s %s, %s %s, %s %s, %s %s, %s %s))'                                   %(left, bottom, left, top, right, top,
229                  %(left, bottom, left, top, right, top, right, bottom, left, bottom))                                    right, bottom, left, bottom))
230            # create a geometry which can be passed to the layer as spatial filter
231          if ogrlayer.GetSpatialRef():          bboxpolygon = ogr.CreateGeometryFromWkt(
232                  bboxpolygon.AssignSpatialReference(ogrlayer.GetSpatialRef())                        ('Polygon((%s %s, %s %s, %s %s,%s %s, %s %s))'
233                                     %(left, bottom, left, top, right, top,
234          ogrlayer.ResetReading()                                    right, bottom, left, bottom)))
235          ogrlayer.SetSpatialFilter(bboxpolygon)  
236          numFeatures = ogrlayer.GetFeatureCount()          if ogrlayer.GetSpatialRef():
237          for feature in range(numFeatures):              bboxpolygon.AssignSpatialReference(ogrlayer.GetSpatialRef())
238                  nextFeature = ogrlayer.GetNextFeature()  
239                  yield cls(ogrlayer, nextFeature.GetFID())          ogrlayer.ResetReading()
240          ogrlayer.SetSpatialFilter(None)          #ogrlayer.SetSpatialFilterRect(left, bottom, right, top)
241          bboxpolygon.Destroy()          ogrlayer.SetSpatialFilter(bboxpolygon)
242            numFeatures = ogrlayer.GetFeatureCount()
243            print numFeatures
244            for feature in range(numFeatures):
245                nextFeature = ogrlayer.GetNextFeature()
246                yield cls(ogrlayer, nextFeature.GetFID())
247            ogrlayer.SetSpatialFilter(None)
248            bboxpolygon.Destroy()
249    
250      def AllShapes(self):      def AllShapes(self):
251          """Return an iterable over the shapes in the shape store."""          """Return an iterable over the shapes in the shape store."""
252          for i in xrange(self.NumShapes()):          self.ogrlayer.ResetReading()
253              yield OGRShape(self.ogrlayer, i)          nextFeature = self.ogrlayer.GetNextFeature()
254            while nextFeature is not None:
255                yield OGRShape(self.ogrlayer, nextFeature.GetFID())
256                nextFeature = self.ogrlayer.GetNextFeature()
257    
258      def Shape(self, index):      def Shape(self, index):
259          """Return the shape with index index"""          """Return the shape with index index"""
# Line 218  class OGRTable: Line 277  class OGRTable:
277      """A Table for an ogr file      """A Table for an ogr file
278      """      """
279    
280      def __init__(self, ds, layer):      def __init__(self, ds, layer, id_column):
281          """Initialize the OGRTable.          """Initialize the OGRTable.
282    
283             ds should be an instance of OGRDatasource.          ds should be an instance of OGRDatasource.
284             layer should be an instance of OGRLayer.          layer should be an instance of OGRLayer.
285          """          """
286    
287          self.datasource = ds          self.datasource = ds
288          self.layer = layer          self.layer = layer
289          self.tablename = layer.GetName()          self.tablename = layer.GetName()
290            self.id_column = id_column
291    
292          # Map column names and indices to column objects.          # Map column names and indices to column objects.
293          self.column_map = {}          self.column_map = {}
294    
295            # Map feature ids to ordinals.
296            self._map_ords_and_ids()
297    
298          self._fetch_table_information()          self._fetch_table_information()
299    
300      def _fetch_table_information(self):      def _fetch_table_information(self):
301          """Internal: Update information about the table"""          """Internal: Update information about the table"""
302          self.columns = []          self.columns = []
303    
304          layerdefn = self.layer.GetLayerDefn()          layerdefn = self.layer.GetLayerDefn()
305          for i in range(layerdefn.GetFieldCount()):          for i in range(layerdefn.GetFieldCount()):
306                  fielddef = layerdefn.GetFieldDefn(i)              fielddef = layerdefn.GetFieldDefn(i)
307                  fieldname = fielddef.GetName()              fieldname = fielddef.GetName()
308                  fieldtype = fieldtype_map[fielddef.GetType()]              fieldtype = fieldtype_map[fielddef.GetType()]
309                  fieldindex = layerdefn.GetFieldIndex(fieldname)              fieldindex = layerdefn.GetFieldIndex(fieldname)
310                  col = OGRColumn(fieldname, fieldtype, fieldindex)              col = OGRColumn(fieldname, fieldtype, fieldindex)
311                  if col is not None:              if col is not None:
312                          self.columns.append(col)                  self.columns.append(col)
313    
314          for col in self.columns:          for col in self.columns:
315              self.column_map[col.name] = col              self.column_map[col.name] = col
316              self.column_map[col.index] = col              self.column_map[col.index] = col
317    
318        def _map_ords_and_ids(self):
319            self.ordinals = {}
320            self.ids = {}
321    
322            lay = self.datasource.ExecuteSQL(
323                    "SELECT %s from %s"
324                    %(self.id_column, self.tablename))
325            lay.ResetReading()
326            nextFeature = lay.GetNextFeature()
327            ord = 0
328            while nextFeature is not None:
329                id = nextFeature.GetFID()
330                self.ordinals[ord] = id
331                self.ids[id] = ord
332                nextFeature = lay.GetNextFeature()
333                ord = ord + 1
334            self.datasource.ReleaseResultSet(lay)
335    
336      def TableName(self):      def TableName(self):
337          """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"""
338          return self.tablename          return self.tablename
# Line 259  class OGRTable: Line 340  class OGRTable:
340      def Title(self):      def Title(self):
341          """Return the title of the table.          """Return the title of the table.
342    
343          The title is currently fixed and equal to the tablename          The title is currently
344          """          """
345          return self.tablename          return self.tablename
346    
# Line 268  class OGRTable: Line 349  class OGRTable:
349          return ()          return ()
350    
351      def NumColumns(self):      def NumColumns(self):
352          """Return the number of columns."""          """Return the number of columns."""
353          return len(self.columns)          return len(self.columns)
354    
355      def Columns(self):      def Columns(self):
356          """Return all columns."""          """Return all columns."""
357          return self.columns          return self.columns
358    
359      def Column(self, col):      def Column(self, col):
360          """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."""
361          return self.column_map[col]          return self.column_map[col]
362    
363      def HasColumn(self, col):      def HasColumn(self, col):
364          """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
365            integer.
366            """
367          return self.column_map.has_key(col)          return self.column_map.has_key(col)
368    
369      def NumRows(self):      def NumRows(self):
370          """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
371          return self.layer.GetFeatureCount()          features in the layer.
372            """
373            return self.layer.GetFeatureCount()
374    
375      def RowIdToOrdinal(self, gid):      def RowIdToOrdinal(self, gid):
376          """Return the row ordinal given its id"""          """Return the row ordinal given its id"""
377          return self.layer.GetFeature(gid).GetFID()          if gid < 0:
378                return gid
379            else:
380                ord = self.ids[gid]
381                return ord
382    #        lay = self.datasource.ExecuteSQL(
383     #               "SELECT COUNT(%s) From %s where FID < %s"
384      #              %(self.id_column, self.tablename, gid))
385       #     ord = lay.GetFeature(0).GetField(0)
386        #    self.datasource.ReleaseResultSet(lay)
387     #       return ord
388    
389      def RowOrdinalToId(self, num):      def RowOrdinalToId(self, num):
390          """Return the rowid for given its ordinal"""          """Return the rowid for given its ordinal"""
391          return self.layer.GetFeature(num).GetFID()  #        lay = self.datasource.ExecuteSQL(
392     #               "SELECT FID From %s"
393      #              %(self.tablename))
394       #     for i in range(num):
395        #        lay.GetNextFeature()
396         #   id = lay.GetNextFeature().GetField(0)
397          #  self.datasource.ReleaseResultSet(lay)
398            if num >= 0:
399                id = self.ordinals[num]
400                return id
401            else:
402                return num
403    
404      def ReadRowAsDict(self, row, row_is_ordinal = 0):      def ReadRowAsDict(self, row, row_is_ordinal = 0):
405          """Return a dictionary which contains all the fields."""          """Return a dictionary which contains all the fields."""
406          layerdef = self.layer.GetLayerDefn()          if row_is_ordinal == 1:
407          feature = self.layer.GetFeature(row)              rowId = self.RowOrdinalToId(row)
408          result = {}          else:
409          for i in range(feature.GetFieldCount()):              rowId = row
410                  fielddef = layerdef.GetFieldDefn(i)          layerdef = self.layer.GetLayerDefn()
411                  result[fielddef.GetName()] = feature.GetField(i)          feature = self.layer.GetFeature(rowId)
412            result = {}
413            for i in range(len(self.columns)):
414                fielddef = layerdef.GetFieldDefn(i)
415                if feature is not None:
416                    result[self.columns[i].name] = feature.GetField(i)
417                else:
418                    result[fielddef.GetName()] = None
419          return result          return result
420    
421      def ReadValue(self, row, col, row_is_ordinal = 0):      def ReadValue(self, row, col, row_is_ordinal = 0):
422          """Return the requested value."""          """Return the requested value."""
423          if col is None:          if col is None:
424                  return None              return None
425          else:          else:
426                  feature = self.layer.GetFeature(row)              feature = self.layer.GetFeature(row)
427                  return feature.GetField(col)          return feature.GetField(col)
428    
429      def ValueRange(self, col):      def ValueRange(self, col):
430          """Return the value range of the given column (given as string)."""          """Return the value range of the given column (given as string)."""
431          result = self.datasource.ExecuteSQL("SELECT min(%s), max(%s) FROM %s"          result = self.datasource.ExecuteSQL("SELECT min(%s), max(%s) FROM %s"
432                  %(col, col, self.layer.GetName()))                  %(col, col, self.layer.GetName()))
433          result.ResetReading()          result.ResetReading()
434          feature = result.GetNextFeature()          feature = result.GetNextFeature()
435          try:          try:
436                  min = feature.GetField(0)              min = feature.GetField(0)
437                  max = feature.GetField(1)              max = feature.GetField(1)
438          except:          except:
439                  min = 0              min = 0
440                  max = 0              max = 0
441          self.datasource.ReleaseResultSet(result)          self.datasource.ReleaseResultSet(result)
442          return (min, max)          return (min, max)
443    
444      def UniqueValues(self, col):      def UniqueValues(self, col):
445          """Return all the values being found in the column (given as string)."""          """Return all the values being found in the column (given as string).
446          result = self.datasource.ExecuteSQL("SELECT DISTINCT %s FROM %s ORDER BY %s" %(col, self.layer.GetName(),col))          """
447          values = []          result = self.datasource.ExecuteSQL((
448          while 1:                      "SELECT DISTINCT %s FROM %s ORDER BY %s"
449                  feature = result.GetNextFeature()                       %(col,self.layer.GetName(),col)))
450                  if feature is None:          values = []
451                          break          while 1:
452                  values.append(feature.GetField(0))              feature = result.GetNextFeature()
453          self.datasource.ReleaseResultSet(result)              if feature is None:
454                    break
455                values.append(feature.GetField(0))
456            self.datasource.ReleaseResultSet(result)
457          return values          return values
458    
459      def SimpleQuery(self, left, comparison, right):      def SimpleQuery(self, left, comparison, right):
460          """Return the FIDs resulting from the given query."""          """Return the FIDs resulting from the given query."""
461          if comparison not in ("==", "!=", "<", "<=", ">=", ">"):          if comparison not in ("==", "!=", "<", "<=", ">=", ">"):
462              raise ValueError("Comparison operator %r not allowed" % comparison)              raise ValueError("Comparison operator %r not allowed" %comparison)
463    
464          if comparison == "==":          if comparison == "==":
465              comparison = "="              comparison = "="
# Line 353  class OGRTable: Line 469  class OGRTable:
469          else:          else:
470              right_template = right              right_template = right
471    
472          query = "SELECT FID FROM %s WHERE '%s' %s %s ORDER BY FID" %(self.tablename, left.name, comparison, right_template)          query = ("SELECT %s FROM %s WHERE '%s' %s %s ORDER BY FID"
473                    % (self.id_column, self.tablename,left.name, comparison,
474                       right_template))
475    
476          lay = self.datasource.ExecuteSQL(query)          lay = self.datasource.ExecuteSQL(query)
477          result = []          result = []
478          while 1:          while lay is not None:
479              feature = lay.GetNextFeature()              feature = lay.GetNextFeature()
480              if feature is None:              if feature is None:
481                  break                  break
482              result.append(feature.GetField(0))              result.append(feature.GetField(0))
483          self.datasource.ReleaseResultSet(lay)          if lay is not None:
484                self.datasource.ReleaseResultSet(lay)
485          return result          return result
486    
487    

Legend:
Removed from v.2437  
changed lines
  Added in v.2549

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26