Introduce FileShapeStore

Jan-Oliver Wagner jan at intevation.de
Tue Mar 29 20:23:26 CEST 2005


Hi Bernhard,

On Mon, Mar 14, 2005 at 09:11:33PM +0100, Bernhard Herzog wrote:
>...

I considered all of your comments.
Attached is the updated patch.

Any comments left?

	Jan
-- 
Jan-Oliver Wagner               http://intevation.de/~jan/

Intevation GmbH                      http://intevation.de/
FreeGIS                                http://freegis.org/
-------------- next part --------------
Index: data.py
===================================================================
RCS file: /thubanrepository/thuban/Thuban/Model/data.py,v
retrieving revision 1.15
diff -u -3 -p -r1.15 data.py
--- data.py	24 Nov 2003 19:23:08 -0000	1.15
+++ data.py	29 Mar 2005 18:10:31 -0000
@@ -112,29 +112,106 @@ class ShapeTable(transientdb.AutoTransie
         """Return a tuple containing the shapestore"""
         return (self.store(),)
 
+# XXX: (this statement should be kept in mind when re-engeneering)
+#
+# From a desing POV it was wrong to distinguish between table and
+# shapestore.  In hindsight the only reason for doing so was that the
+# shapelib has different objects for the shapefile(s) and the dbf file,
+# which of course matches the way the data is organized into different
+# files.  So the distinction between shapestore and table is an artifact
+# of the shapefile format.  When we added the postgis support we should
+# have adopted the table interface for the entire shape store, making the
+# geometry data an additional column for those shape stores that don't
+# store the geometries in columns in the first place.
+
+class FileShapeStore:
+
+    """The base class to derive any file-based ShapeStore from.
+
+    This class contains all information that is needed by a
+    loader routine to actually load the shapestore.
+    This essentially means that the class contains all required information
+    to save the shapestore specification (i.e. in a .thuban file).
+    """
+
+    def __init__(self, filename, filetype, layername = None):
+        """Initialize the base class with main parameters.
+
+        filename  -- the source filename.
+                     This filename will be converted to an absolute filename.
+                     The filename will be interpreted relative to that anyway,
+                     but when saving a session we need to compare absolute paths
+                     and it's usually safer to always work with absolute paths.
+        filetype  -- The type of the filename.
+                     Known and used types are: "shapefile"
+        layername -- a string representing a layer within the file shape store.
+                     Some file formats support to contain several layers, or
+                     at least the ogr library says so.
+                     For those filetypes who don't, the layername can be ignored
+                     and by default it is None.
+        """
+        self._filename = os.path.abspath(filename)
+        self._filetype = filetype
+        self._layername = layername
+        self._bbox = None
+        self._table = None
+
+    def FileName(self):
+        """Return the filename used to open the shapestore.
+
+        The filename can only be set via __init__ method.
+        """
+        return self._filename
+
+    def FileType(self):
+        """Return the filetype.
+
+        The filetype has to be set in via __init__ method.
+        """
+        return self._filetype
+
+    def layer_name(self):
+        """Return the layername.
+
+        This could be None if the shapestore type only supports a single
+        layer.
+        """
+        return self._layername
+
+    # Design/Implementation note:
+    # It is not a good idea to have a implementation for a
+    # "setBoundingBox" or BoundingBox # in this base class.
+    # In future this data might change during
+    # a Thuban session and thus can not be kept statically here.
+    # It is expected that for many derived classes the bbox must
+    # be retrieved each time anew.
+
+    def BoundingBox(self):
+        """Return the bounding box of the shapes in the shape store.
+
+        The coordinate system used is whatever was used in the shape store.
+        If the shape store is empty, return None.
+        """
+        raise NotImplementedError
 
-class ShapefileStore:
+class ShapefileStore(FileShapeStore):
 
     """Combine a shapefile and the corresponding DBF file into one object"""
 
     def __init__(self, session, filename):
-        # Make the filename absolute. The filename will be
-        # interpreted relative to that anyway, but when saving a
-        # session we need to compare absolute paths and it's usually
-        # safer to always work with absolute paths.
-        self.filename = os.path.abspath(filename)
+        FileShapeStore.__init__(self, filename, "shapefile")
 
         self.dbftable = table.DBFTable(filename)
-        self.table = ShapeTable(self, session.TransientDB(), self.dbftable)
+        self._table = ShapeTable(self, session.TransientDB(), self.dbftable)
         self._open_shapefile()
 
     def _open_shapefile(self):
-        self.shapefile = shapelib.ShapeFile(self.filename)
+        self.shapefile = shapelib.ShapeFile(self.FileName())
         self.numshapes, shapetype, mins, maxs = self.shapefile.info()
         if self.numshapes:
-            self.bbox = mins[:2] + maxs[:2]
+            self._bbox = mins[:2] + maxs[:2]
         else:
-            self.bbox = None
+            self._bbox = None
         self.shapetype = shapelib_shapetypes[shapetype]
 
         # estimate a good depth for the quad tree. Each depth multiplies
@@ -148,22 +225,10 @@ class ShapefileStore:
         self.shapetree = shptree.SHPTree(self.shapefile.cobject(), 2,
                                          maxdepth)
 
-    def Table(self):
-        """Return the table containing the attribute data"""
-        return self.table
-
     def Shapefile(self):
         """Return the shapefile object"""
         return self.shapefile
 
-    def FileName(self):
-        """Return the filename used to open the shapefile"""
-        return self.filename
-
-    def FileType(self):
-        """Return the filetype. This is always the string 'shapefile'"""
-        return "shapefile"
-
     def ShapeType(self):
         """Return the type of the shapes in the shapestore.
 
@@ -186,6 +251,10 @@ class ShapefileStore:
         """
         return ()
 
+    def Table(self):
+        """Return the table containing the attribute data."""
+        return self._table
+
     def OrigShapeStore(self):
         """Return None.
 
@@ -193,14 +262,6 @@ class ShapefileStore:
         """
         return None
 
-    def BoundingBox(self):
-        """Return the bounding box of the shapes in the shapestore.
-
-        The coordinate system used is whatever was used in the shapefile.
-        If the shapefile is empty, return None.
-        """
-        return self.bbox
-
     def ShapesInRegion(self, bbox):
         """Return an iterable over the shapes that overlap the bounding box.
 
@@ -225,6 +286,13 @@ class ShapefileStore:
         """Return the shape with index index"""
         return ShapefileShape(self.shapefile, index)
 
+    def BoundingBox(self):
+        """Return the bounding box of the shapes in the shape store.
+
+        The coordinate system used is whatever was used in the shape store.
+        If the shape store is empty, return None.
+        """
+        return self._bbox
 
 
 class DerivedShapeStore:
Index: save.py
===================================================================
RCS file: /thubanrepository/thuban/Thuban/Model/save.py,v
retrieving revision 1.43
diff -u -3 -p -r1.43 save.py
--- save.py	28 Jan 2005 15:54:00 -0000	1.43
+++ save.py	29 Mar 2005 18:10:31 -0000
@@ -26,7 +26,7 @@ from Thuban.Model.classification import 
     ClassGroupDefault, ClassGroupSingleton, ClassGroupRange, ClassGroupMap
 from Thuban.Model.transientdb import AutoTransientTable, TransientJoinedTable
 from Thuban.Model.table import DBFTable, FIELDTYPE_STRING
-from Thuban.Model.data import DerivedShapeStore, ShapefileStore, \
+from Thuban.Model.data import DerivedShapeStore, FileShapeStore, \
                               SHAPETYPE_POINT
 
 from Thuban.Model.xmlwriter import XMLWriter
@@ -201,12 +201,12 @@ class SessionSaver(XMLWriter):
                 continue
 
             idvalue = self.define_id(container)
-            if isinstance(container, ShapefileStore):
+            if isinstance(container, FileShapeStore):
                 self.define_id(container.Table(), idvalue)
                 filename = self.prepare_filename(container.FileName())
                 self.write_element("fileshapesource",
                                    {"id": idvalue, "filename": filename,
-                                    "filetype": "shapefile"})
+                                    "filetype": container.FileType()})
             elif isinstance(container, DerivedShapeStore):
                 shapesource, table = container.Dependencies()
                 self.write_element("derivedshapesource",


More information about the Thuban-devel mailing list

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