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)