/[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 2493 by nhueffme, Mon Dec 20 14:13:57 2004 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    
 # Raw data in ogr format  
 RAW_OGRSHAPES = "RAW_OGRSHAPES"  
   
   
29    
30  def has_ogr_support():  def has_ogr_support():
31      """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 38  def has_ogr_support():
38  if ogr is not None:  if ogr is not None:
39      # mapping from ogr-lib shapetype and table constants to our constants      # mapping from ogr-lib shapetype and table constants to our constants
40      ogrlib_shapetypes = {ogr.wkbPolygon: SHAPETYPE_POLYGON,      ogrlib_shapetypes = {ogr.wkbPolygon: SHAPETYPE_POLYGON,
41                         ogr.wkbLineString: SHAPETYPE_ARC,                  ogr.wkbLineString: SHAPETYPE_ARC,
42                         ogr.wkbPoint: SHAPETYPE_POINT}                  ogr.wkbPoint: SHAPETYPE_POINT}
43    
44      fieldtype_map = {ogr.OFTString: table.FIELDTYPE_STRING,      fieldtype_map = {ogr.OFTString: table.FIELDTYPE_STRING,
45          ogr.OFTInteger: table.FIELDTYPE_INT,                  ogr.OFTInteger: table.FIELDTYPE_INT,
46          ogr.OFTReal: table.FIELDTYPE_DOUBLE}                  ogr.OFTReal: table.FIELDTYPE_DOUBLE}
47    
48    
49  class OGRShape:  class OGRShape:
# Line 62  class OGRShape: Line 58  class OGRShape:
58          """          """
59          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)
60          """          """
61          shape = self.ogrlayer.GetFeature(self.shapeid)          shape = self.ogrlayer.GetFeature(self.shapeid)
62          geom = shape.GetGeometryRef()          geom = shape.GetGeometryRef()
63          minx, maxx, miny, maxy = geom.GetEnvelope()          minx, maxx, miny, maxy = geom.GetEnvelope()
64          return (minx, miny, maxx, maxy)          return (minx, miny, maxx, maxy)
65    
66      def ShapeID(self):      def ShapeID(self):
67          return self.shapeid          return self.shapeid
68    
69      # diese Methode funktioniert vielleicht noch nicht f�r andere Formate als shp      # diese Methode funktioniert vielleicht noch nicht f�r andere Formate
70        #als shp
71      #(wenn ein polygon aus mehreren      #(wenn ein polygon aus mehreren
72      # Ringen besteht o.�., hat ein Geometry-Objekt mehr als einen GeometryRef().----------------------------      # Ringen besteht o.�., hat ein Geometry-Objekt mehr als einen
73        #GeometryRef().---------
74      def Points(self):      def Points(self):
75          """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"""
76          feature = self.ogrlayer.GetFeature(self.shapeid)          feature = self.ogrlayer.GetFeature(self.shapeid)
77          geometry = feature.GetGeometryRef()          geom = feature.GetGeometryRef()
78          while geometry.GetGeometryCount() != 0:          shape = []
79                  geometry = geometry.GetGeometryRef(0)          # if geometry object is of type point or line
80          points = []          if geom.GetGeometryCount() == 0:
81          for point in range(geometry.GetPointCount()):              points =[]
82                  x = geometry.GetX(point)              for point in range(geom.GetPointCount()):
83                  y = geometry.GetY(point)                  x = geom.GetX(point)
84                  points.append((x, y))                  y = geom.GetY(point)
85          points = [points]                  points.append((x, y))
86          return points              return [points]
87            # if geometry object is of type polygon or multipolygon
88            for i in range(geom.GetGeometryCount()):
89                points = []
90                geometry = geom.GetGeometryRef(i)
91                # if geometry object is polygon
92                if geometry.GetGeometryCount() == 0:
93                    for point in range(geometry.GetPointCount()):
94                        x = geometry.GetX(point)
95                        y = geometry.GetY(point)
96                        points.append((x, y))
97                    shape.append(points)
98                # if geometry object is of type multipolygon
99                else:
100                    for j in range(geometry.GetGeometryCount()):
101                        points = []
102                        subgeom = geometry.GetGeometryRef(j)
103                        for point in range(subgeom.GetPointCount()):
104                            x = subgeom.GetX(point)
105                            y = subgeom.GetY(point)
106                            points.append((x, y))
107                        shape.append(points)
108            return shape
109    
110      def RawData(self):      def RawData(self):
111          """Return the shape id to use with the shapestore"""          """Return the shape id to use with the shapestore"""
# Line 98  class OGRShape: Line 118  class OGRShape:
118    
119  class OGRShapeStore:  class OGRShapeStore:
120    
121      """Corresponds to an OGRLayer object, containing features/shapes and providing all methods Thuban      """Corresponds to an OGRLayer object, containing features/shapes and
122         needs."""         providing all methods Thuban needs.
123        """
124    
125      def __init__(self, session, filename, layername):      def __init__(self, session, filename, layername):
126          # Make the filename absolute. The filename will be          # Make the filename absolute. The filename will be
# Line 107  class OGRShapeStore: Line 128  class OGRShapeStore:
128          # session we need to compare absolute paths and it's usually          # session we need to compare absolute paths and it's usually
129          # safer to always work with absolute paths.          # safer to always work with absolute paths.
130    
131          self.filename = os.path.abspath(filename)          self.filename = os.path.abspath(filename)
132          self.layername = layername          self.layername = layername
133    
134          self.ogrdatasource = ogr.Open(self.filename)          self.ogrdatasource = ogr.Open(self.filename)
135          self.ogrlayer = (self.ogrdatasource).GetLayerByName(layername)          self.ogrlayer = (self.ogrdatasource).GetLayerByName(layername)
136          self.table = OGRTable(self.ogrdatasource, self.ogrlayer)          self.table = OGRTable(self.ogrdatasource, self.ogrlayer)
137    
138          self._open_ogrlayer(layername)          self._open_ogrlayer(layername)
139    
140      def _open_ogrlayer(self, layername):      def _open_ogrlayer(self, layername):
141          self.numshapes = self.ogrlayer.GetFeatureCount()          self.numshapes = self.ogrlayer.GetFeatureCount()
142          self.shapetype = self.ogrlayer.GetLayerDefn().GetGeomType()          self.shapetype = self.ogrlayer.GetLayerDefn().GetGeomType()
143          extent = self.ogrlayer.GetExtent()          extent = self.ogrlayer.GetExtent()
   
         if extent:  
                 self.bbox = [extent[0], extent[2], extent[1], extent[3]]  
         else:  
                 self.bbox = None  
144    
145          self.shapetype = ogrlib_shapetypes[self.shapetype]          if extent:
146                self.bbox = [extent[0], extent[2], extent[1], extent[3]]
147            else:
148                self.bbox = None
149    
150            self.shapetype = ogrlib_shapetypes[self.shapetype]
151    
152      def OGRLayer(self):      def OGRLayer(self):
153          """Return the OGRLayer object"""          """Return the OGRLayer object"""
# Line 148  class OGRShapeStore: Line 169  class OGRShapeStore:
169          return self.shapetype          return self.shapetype
170    
171      def RawShapeFormat(self):      def RawShapeFormat(self):
172          """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"""
173          return RAW_OGRSHAPES          return RAW_PYTHON
174    
175      def NumShapes(self):      def NumShapes(self):
176          """Return the number of shapes in the shape store"""          """Return the number of shapes in the shape store"""
# Line 167  class OGRShapeStore: Line 188  class OGRShapeStore:
188          form (minx, miny, maxx, maxy) in the coordinate system of the          form (minx, miny, maxx, maxy) in the coordinate system of the
189          shape store.          shape store.
190    
191          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.
192          """          """
193          # Bind a few globals to locals to make it a bit faster          # Bind a few globals to locals to make it a bit faster
194          cls = OGRShape          cls = OGRShape
# Line 175  class OGRShapeStore: Line 196  class OGRShapeStore:
196    
197          left, bottom, right, top = bbox          left, bottom, right, top = bbox
198    
199          # 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
200          bboxpolygon = ogr.CreateGeometryFromWkt('Polygon((%s %s, %s %s, %s %s, %s %s, %s %s))'          bboxpolygon = ogr.CreateGeometryFromWkt(
201                  %(left, bottom, left, top, right, top, right, bottom, left, bottom))                        ('Polygon((%s %s, %s %s, %s %s,%s %s, %s %s))'
202                                     %(left, bottom, left, top, right, top,
203          if ogrlayer.GetSpatialRef():                                    right, bottom, left, bottom)))
204                  bboxpolygon.AssignSpatialReference(ogrlayer.GetSpatialRef())  
205            if ogrlayer.GetSpatialRef():
206          ogrlayer.ResetReading()              bboxpolygon.AssignSpatialReference(ogrlayer.GetSpatialRef())
207          ogrlayer.SetSpatialFilter(bboxpolygon)  
208          numFeatures = ogrlayer.GetFeatureCount()          ogrlayer.ResetReading()
209          for feature in range(numFeatures):          ogrlayer.SetSpatialFilter(bboxpolygon)
210                  nextFeature = ogrlayer.GetNextFeature()          numFeatures = ogrlayer.GetFeatureCount()
211                  yield cls(ogrlayer, nextFeature.GetFID())          for feature in range(numFeatures):
212          ogrlayer.SetSpatialFilter(None)              nextFeature = ogrlayer.GetNextFeature()
213          bboxpolygon.Destroy()              yield cls(ogrlayer, nextFeature.GetFID())
214            ogrlayer.SetSpatialFilter(None)
215            bboxpolygon.Destroy()
216    
217      def AllShapes(self):      def AllShapes(self):
218          """Return an iterable over the shapes in the shape store."""          """Return an iterable over the shapes in the shape store."""
# Line 221  class OGRTable: Line 244  class OGRTable:
244      def __init__(self, ds, layer):      def __init__(self, ds, layer):
245          """Initialize the OGRTable.          """Initialize the OGRTable.
246    
247             ds should be an instance of OGRDatasource.          ds should be an instance of OGRDatasource.
248             layer should be an instance of OGRLayer.          layer should be an instance of OGRLayer.
249          """          """
250    
251          self.datasource = ds          self.datasource = ds
252          self.layer = layer          self.layer = layer
253          self.tablename = layer.GetName()          self.tablename = layer.GetName()
254    
255          # Map column names and indices to column objects.          # Map column names and indices to column objects.
256          self.column_map = {}          self.column_map = {}
# Line 238  class OGRTable: Line 261  class OGRTable:
261          """Internal: Update information about the table"""          """Internal: Update information about the table"""
262          self.columns = []          self.columns = []
263    
264          layerdefn = self.layer.GetLayerDefn()          layerdefn = self.layer.GetLayerDefn()
265          for i in range(layerdefn.GetFieldCount()):          for i in range(layerdefn.GetFieldCount()):
266                  fielddef = layerdefn.GetFieldDefn(i)              fielddef = layerdefn.GetFieldDefn(i)
267                  fieldname = fielddef.GetName()              fieldname = fielddef.GetName()
268                  fieldtype = fieldtype_map[fielddef.GetType()]              fieldtype = fieldtype_map[fielddef.GetType()]
269                  fieldindex = layerdefn.GetFieldIndex(fieldname)              fieldindex = layerdefn.GetFieldIndex(fieldname)
270                  col = OGRColumn(fieldname, fieldtype, fieldindex)              col = OGRColumn(fieldname, fieldtype, fieldindex)
271                  if col is not None:              if col is not None:
272                          self.columns.append(col)                  self.columns.append(col)
273    
274          for col in self.columns:          for col in self.columns:
275              self.column_map[col.name] = col              self.column_map[col.name] = col
# Line 268  class OGRTable: Line 291  class OGRTable:
291          return ()          return ()
292    
293      def NumColumns(self):      def NumColumns(self):
294          """Return the number of columns."""          """Return the number of columns."""
295          return len(self.columns)          return len(self.columns)
296    
297      def Columns(self):      def Columns(self):
298          """Return all columns."""          """Return all columns."""
299          return self.columns          return self.columns
300    
301      def Column(self, col):      def Column(self, col):
302          """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."""
303          return self.column_map[col]          return self.column_map[col]
304    
305      def HasColumn(self, col):      def HasColumn(self, col):
306          """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
307            integer.
308            """
309          return self.column_map.has_key(col)          return self.column_map.has_key(col)
310    
311      def NumRows(self):      def NumRows(self):
312          """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
313          return self.layer.GetFeatureCount()          features in the layer.
314            """
315            return self.layer.GetFeatureCount()
316    
317      def RowIdToOrdinal(self, gid):      def RowIdToOrdinal(self, gid):
318          """Return the row ordinal given its id"""          """Return the row ordinal given its id"""
319          return self.layer.GetFeature(gid).GetFID()          return self.layer.GetFeature(gid).GetFID()
320    
321      def RowOrdinalToId(self, num):      def RowOrdinalToId(self, num):
322          """Return the rowid for given its ordinal"""          """Return the rowid for given its ordinal"""
323          return self.layer.GetFeature(num).GetFID()          return self.layer.GetFeature(num).GetFID()
324    
325      def ReadRowAsDict(self, row, row_is_ordinal = 0):      def ReadRowAsDict(self, row, row_is_ordinal = 0):
326          """Return a dictionary which contains all the fields."""          """Return a dictionary which contains all the fields."""
327          layerdef = self.layer.GetLayerDefn()          layerdef = self.layer.GetLayerDefn()
328          feature = self.layer.GetFeature(row)          feature = self.layer.GetFeature(row)
329          result = {}          result = {}
330          for i in range(feature.GetFieldCount()):          for i in range(feature.GetFieldCount()):
331                  fielddef = layerdef.GetFieldDefn(i)              fielddef = layerdef.GetFieldDefn(i)
332                  result[fielddef.GetName()] = feature.GetField(i)              result[fielddef.GetName()] = feature.GetField(i)
333          return result          return result
334    
335      def ReadValue(self, row, col, row_is_ordinal = 0):      def ReadValue(self, row, col, row_is_ordinal = 0):
336          """Return the requested value."""          """Return the requested value."""
337          if col is None:          if col is None:
338                  return None              return None
339          else:          else:
340                  feature = self.layer.GetFeature(row)              feature = self.layer.GetFeature(row)
341                  return feature.GetField(col)          return feature.GetField(col)
342    
343      def ValueRange(self, col):      def ValueRange(self, col):
344          """Return the value range of the given column (given as string)."""          """Return the value range of the given column (given as string)."""
345          result = self.datasource.ExecuteSQL("SELECT min(%s), max(%s) FROM %s"          result = self.datasource.ExecuteSQL("SELECT min(%s), max(%s) FROM %s"
346                  %(col, col, self.layer.GetName()))                  %(col, col, self.layer.GetName()))
347          result.ResetReading()          result.ResetReading()
348          feature = result.GetNextFeature()          feature = result.GetNextFeature()
349          try:          try:
350                  min = feature.GetField(0)              min = feature.GetField(0)
351                  max = feature.GetField(1)              max = feature.GetField(1)
352          except:          except:
353                  min = 0              min = 0
354                  max = 0              max = 0
355          self.datasource.ReleaseResultSet(result)          self.datasource.ReleaseResultSet(result)
356          return (min, max)          return (min, max)
357    
358      def UniqueValues(self, col):      def UniqueValues(self, col):
359          """Return all the values being found in the column (given as string)."""          """Return all the values being found in the column (given as string).
360          result = self.datasource.ExecuteSQL("SELECT DISTINCT %s FROM %s ORDER BY %s" %(col, self.layer.GetName(),col))          """
361          values = []          result = self.datasource.ExecuteSQL((
362          while 1:                      "SELECT DISTINCT %s FROM %s ORDER BY %s"
363                  feature = result.GetNextFeature()                       %(col,self.layer.GetName(),col)))
364                  if feature is None:          values = []
365                          break          while 1:
366                  values.append(feature.GetField(0))              feature = result.GetNextFeature()
367          self.datasource.ReleaseResultSet(result)              if feature is None:
368                    break
369                values.append(feature.GetField(0))
370            self.datasource.ReleaseResultSet(result)
371          return values          return values
372    
373      def SimpleQuery(self, left, comparison, right):      def SimpleQuery(self, left, comparison, right):
374          """Return the FIDs resulting from the given query."""          """Return the FIDs resulting from the given query."""
375          if comparison not in ("==", "!=", "<", "<=", ">=", ">"):          if comparison not in ("==", "!=", "<", "<=", ">=", ">"):
376              raise ValueError("Comparison operator %r not allowed" % comparison)              raise ValueError("Comparison operator %r not allowed" %comparison)
377    
378          if comparison == "==":          if comparison == "==":
379              comparison = "="              comparison = "="
# Line 353  class OGRTable: Line 383  class OGRTable:
383          else:          else:
384              right_template = right              right_template = right
385    
386          query = "SELECT FID FROM %s WHERE '%s' %s %s ORDER BY FID" %(self.tablename, left.name, comparison, right_template)          query = ("SELECT FID FROM %s WHERE '%s' %s %s ORDER BY FID"
387                    % (self.tablename,left.name, comparison, right_template))
388    
389          lay = self.datasource.ExecuteSQL(query)          lay = self.datasource.ExecuteSQL(query)
390          result = []          result = []
391          while 1:          while lay is not None:
392              feature = lay.GetNextFeature()              feature = lay.GetNextFeature()
393              if feature is None:              if feature is None:
394                  break                  break
395              result.append(feature.GetField(0))              result.append(feature.GetField(0))
396          self.datasource.ReleaseResultSet(lay)          self.datasource.ReleaseResultSet(lay)
397          return result          return result
398    
399    

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26