jan: thuban/Extensions/ogr ogrshapes.py,1.6,1.7

cvs@intevation.de cvs at intevation.de
Thu Apr 28 11:39:10 CEST 2005


Author: jan

Update of /thubanrepository/thuban/Extensions/ogr
In directory doto:/tmp/cvs-serv31419

Modified Files:
	ogrshapes.py 
Log Message:
(OGRFileShapeStore): New. This
class ist to be used for any file-based shape stores
accessed through OGR.


Index: ogrshapes.py
===================================================================
RCS file: /thubanrepository/thuban/Extensions/ogr/ogrshapes.py,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- ogrshapes.py	4 Mar 2005 15:07:59 -0000	1.6
+++ ogrshapes.py	28 Apr 2005 09:39:08 -0000	1.7
@@ -25,6 +25,7 @@
 
 from Thuban.Model.data import SHAPETYPE_POLYGON, SHAPETYPE_ARC, SHAPETYPE_POINT
 from Thuban.Model.data import RAW_PYTHON, RAW_SHAPEFILE, RAW_WKT
+from Thuban.Model.data import FileShapeStore
 
 def has_ogr_support():
     """Return whether this Thuban instance supports ogr file formats
@@ -229,8 +230,16 @@
 class OGRShapeStore:
     """Corresponds to an OGRLayer object, containing features/shapes and
        providing the same methods like ShapefileStore.
+
+       In fact, for all file based shape stores, the class OGRFileShapeStore
+       should be used. Only database shape stores should be
+       used with OGRShapeStore. It is subject to re-factoring
+       to end up with better class names and sensible base classes.
     """
 
+    # TODO: re-factor this class to be not responsible for file-based
+    # stores anymore.
+
     def __init__(self, session, filename, layername, id_column = None):
         """Initialize the shapestore.
 
@@ -414,6 +423,172 @@
         """Return the id_column.
         """
         return self.id_column
+
+class OGRFileShapeStore(FileShapeStore):
+    """Corresponds to an OGRLayer object, containing features/shapes and
+       providing the same methods like ShapefileStore.
+    """
+
+    def __init__(self, session, filename, layername, id_column = None):
+        """Initialize the shapestore.
+
+        All required information is loaded from the datasource.
+        """
+        self._bbox = None
+        self.ogrdatasource = ogr.Open(filename)
+
+        # filetype is depending on the driver used to open the file.
+        self._filetype = self.ogrdatasource.GetDriver().GetName()
+        if self._filetype == 'ESRI Shapefile':
+            self._filetype = "shapefile"
+        FileShapeStore.__init__(self, filename,
+                                sublayer_name = layername)
+
+        self.ogrlayer = (self.ogrdatasource).GetLayerByName(layername)
+
+        self._table = OGRTable(session, self.ogrdatasource, self.ogrlayer,
+                               id_column)
+
+        self._open_ogrlayer(layername)
+
+    def _open_ogrlayer(self, layername):
+        """Get all required information from the datasource.
+        """
+        self.numshapes = self.ogrlayer.GetFeatureCount()
+        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
+
+        try:
+            self.shapetype = ogrlib_shapetypes[self.shapetype]
+        except:
+            # if shapetype is not contained in ogrlib_shapetypes
+            # treat it like SHAPETYPE_UNKNOWN
+            self.shapetype = ogrlib_shapetypes[ogr.wkbUnknown]
+
+        self.shapes = self.shapes()
+
+    def FileType(self):
+        """Return the filetype."""
+        return self._filetype
+
+    def BoundingBox(self):
+        """Return the bounding box of the shapes in the shape file.
+
+        The coordinate system used is whatever was used in the shape file.
+        If the shape file is empty, return None.
+        """
+        return self._bbox
+
+    def shapes(self):
+        """Return a collection of all features as OGRShape objects.
+        """
+        shapes = {}
+        self.ogrlayer.ResetReading()
+
+        nextFeature = self.ogrlayer.GetNextFeature()
+        while nextFeature is not None:
+            fid = nextFeature.GetFID()
+            shape = OGRShape(self, nextFeature)
+            shapes[shape.ShapeID()] = shape
+            nextFeature = self.ogrlayer.GetNextFeature()
+
+        return shapes
+
+    def OGRLayer(self):
+        """Return the OGRLayer object
+        """
+        return self.ogrlayer
+
+    def ShapeType(self):
+        """Return the type of the shapes in the shapestore.
+
+        This is either SHAPETYPE_POINT, SHAPETYPE_ARC, SHAPETYPE_POLYGON,
+        SHAEPTYPE_GEOMCOLL, SHAPETYPE_NONE or SHAPETYPE_UNKNOWN.
+        """
+        return self.shapetype
+
+    def RawShapeFormat(self):
+        """Return the raw data format of the shape data, i.e. RAW_PYTHON
+        """
+        return RAW_PYTHON
+
+    def NumShapes(self):
+        """Return the number of shapes in the shape store
+        """
+        return self.numshapes
+
+    def ShapesInRegion(self, bbox):
+        """Return an iterable over the shapes that overlap the bounding box.
+
+        The bbox parameter should be the bounding box as a tuple in the
+        form (minx, miny, maxx, maxy) in the coordinate system of the
+        shape store.
+        """
+        left, bottom, right, top = bbox
+
+        # create a geometry which can be passed to the layer as spatial filter
+        bboxpolygon = ogr.CreateGeometryFromWkt(
+                      ('Polygon((%s %s, %s %s, %s %s,%s %s, %s %s))'
+                                 %(left, bottom, left, top, right, top,
+                                  right, bottom, left, bottom)))
+
+        if self.ogrlayer.GetSpatialRef():
+            bboxpolygon.AssignSpatialReference(self.ogrlayer.GetSpatialRef())
+
+        self.ogrlayer.ResetReading()
+        #ogrlayer.SetSpatialFilterRect(left, bottom, right, top)
+        self.ogrlayer.SetSpatialFilter(bboxpolygon)
+
+        numFeatures = self.ogrlayer.GetFeatureCount()
+        # if no features are in bbox, return all features as shapesInRegion
+        # (PostGIS sometimes returns no features even if they are within 
+        #  the bounding box)
+        if numFeatures == 0:
+            self.ogrlayer.SetSpatialFilter(None)
+            numFeatures = self.ogrlayer.GetFeatureCount()
+        for feature in range(numFeatures):
+            nextFeature = self.ogrlayer.GetNextFeature()
+            yield self.shapes[nextFeature.GetFID()]
+
+        self.ogrlayer.SetSpatialFilter(None)
+        bboxpolygon.Destroy()
+
+    def AllShapes(self):
+        """Return an iterable over the shapes in the shape store.
+        """
+        for id in range(len(self.shapes)):
+            yield self.shapes[id]
+
+    def Shape(self, fid):
+        """Return the shape with fid = fid
+        """
+        if fid in self.Table().ids.keys():
+            return self.shapes[fid]
+        else:
+            return None
+
+    def Table(self):
+        """Return the table containing the attribute data."""
+        return self._table
+
+    def Dependencies(self):
+        """Return the empty tuple.
+        """
+        return ()
+
+    def OrigShapeStore(self):
+        """Return None."""
+        return None
+
+    def Id_column(self):
+        """Return the id_column.
+        """
+        return None
 
 class OGRTable(transientdb.AutoTransientTable):
     """A Table for an ogr datasource.





More information about the Thuban-devel mailing list

This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)