[Thuban-devel] Re: Base class for Shapes?
Jan-Oliver Wagner
jan at intevation.de
Fri Nov 26 17:55:20 CET 2004
On Thu, Nov 25, 2004 at 10:08:44PM +0100, Bernhard Herzog wrote:
> Jan-Oliver Wagner <jan at intevation.de> writes:
> > on a train travel from Bonn to Osnabrück
> > I worked out an idea about a Base Shape Class.
>
> If it's there to reduce code duplication OK (The bounding box
> computation has been copied several times already). It should not be a
> requirement for shape objects to be derived from that class, though.
I had code reduction in mind.
Why should not all Shape objects share the same base class?
> > The idea is that we might want to have Shapes/Shapestores
> > that are kept in memory instead in a file in order
> > have a opportunity to create/modify them with arbitrary
> > algorithms implemented in Thuban(or in its extensions).
>
> I haven't looked at Ole's code yet, but in the test suite there's
> already a simple shape store that has all the shape data in memory
> (SimpleShapeStore in test/mockgeo.py). It's only there for the tests,
> but the MemoryTable started out that way too.
Damn, I didn't find this. Will look into that code before doing
anything else on this topic.
> > This class "Shape" would also be a first step to redruce
> > the code in that extension. Ongoing steps would be to introduce
> > a MemoryShapeStore with ability to store it as a Shapefile.
>
> Writing shapes to a shapefile is orthogonal of memory shape stores. It
> should be possible to write a function that takes any kind of shapestore
> and writes its contents to a shapefile (or ideally any writable
> shapestore, once we have such a thing in Thuban).
Correct. I should have written with the ability to modify Shapes easily
and create layers without any Shapefile or Database as connection.
> > Ah, and: this can even be ported back to 1_0 ;-)
>
> Why should the shape base class be backported?
The PIROL extension is based on 1.0 and there is no 1.2 yet.
So I thought this extension could be made more lean with
such classes ported to 1.0.
> > --- Thuban/Model/data.py 24 Nov 2003 19:23:08 -0000 1.15
> > +++ Thuban/Model/data.py 24 Nov 2004 21:43:02 -0000
> > @@ -48,8 +48,114 @@ RAW_SHAPEFILE = "RAW_SHAPEFILE"
> > # Raw data in well-known text format
> > RAW_WKT = "RAW_WKT"
> >
> > +class Shape:
> >
> > -class ShapefileShape:
> > + """Base class (Interface) for representing a single Shape.
> > + """
>
> Well, what is it? A base class or an interface? It shouldn't be both.
> The interface should be independent of a particular base class. As for
> interface, most of the larger python projects (twisted and Zope for
> instance) seem to be converging on something like PyProtocols. The
> details vary a bit and we don't need all of it for Thuban, we should go
> in that direction as well. At the very least it will document the
> interfaces we use.
I was not sure myself. In general, Interfaces would be nice,
but as along as we keep compatibility with Python 2.2.1 it is
probably not good to introduce them.
So I was more looking at the base class aspect.
> That sais, it would be OK to have a class that contains the code that's
> currently duplicated in the various shape classes that already exist.
> AFAICT, in the shape classes that come with Thuban, i.e. ShapefileShape,
> PostGISShape and SimpleShape, there are only two things their
> implementations have in common:
> shapeid: In all cases it's passed to __init__, stored in self.shapeid,
> and from there it's returned by the ShapeId() method.
>
> compute_bbox: The method to compute the bounding from the points.
> It's implementation is exactly the same in all three
> cases.
>
> So if we want a base class for common implementation, these would be the
> only things that belong there.
OK.
Aren't there any additional hard requirements all Shape object must have?
What about the RawData for example. Shouldn't there by a default method?
> Your base class has several methods that modify the shape. So, one
> general design issue that we may need to decide is whether shape objects
> are mutable. I would prefer to keep them immutable. If they were
> mutable, what would changing a shape mean? If it were a shape read from
> a shapefile, for instance, would the shapefile automatically be
> modified?
Yes I agree. A base class should be immutable.
> > + def isInBBox(self, bbox):
> > + """Test whether the the shape lies completely within the
> > + given bounding box.
>
> It might be easier to promote bounding boxes to "real" objects. Then
> you could do that kind of bounding box arit
not sure how to do that "arit".
> > +
> > + bbox -- the bounding box as tuple (minx,miny,max,maxy)
> > +
> > + Returns: True if the shape lies within bbox, else False
> > + """
> > + bb_minX, bb_minY, bb_maxX, bb_maxY = bbox
> > + minX, minY, maxX, maxY = self.BBox()
> > +
> > + if minX >= bb_minX and maxX <= bb_maxX and \
> > + minY >= bb_minY and maxY <= bb_maxY:
> > + return True
> > +
> > + return False
> > +
> > + def __str__(self):
> > + return "Shape " + repr(self.shapeid) + ": " + repr(self.points)
> > +
> > +# def intersectsBBox(self, bbox):
> > +# """Test whether the the shape intersects the given bounding box.
> > +# In other words, tests whether at least one point of the shape
> > +# lies within the given bounding box.
> > +#
> > +# bbox -- the bounding box as tuple (minx,miny,max,maxy)
> > +#
> > +# Returns: True if at least one point of the shape lies within
> > +# bbox, else False
> > +# """
> > +# bb_minX, bb_minY, bb_maxX, bb_maxY = bbox
> > +# minX, minY, maxX, maxY = self.BBox()
> > +#
> > +# # test each single point whether it is inside the given bbox
> > +# for part in self.Points():
> > +# for x, y in part:
> > +# if (x >= bb_minX and x <= bb_maxX) and
> > +# (y >= bb_minY and y <= bb_maxY):
> > +# return True
>
> Did you comment that out and forgot to remove it before posting this?
> It's quite buggy :)
yes, that is broken totally and should have been removed before
I made the patch.
>
> > def RawData(self):
> > - """Return the shape id to use with the shapefile"""
> > + """Return the shape id to use with the shapefile.
> > +
> > + XXX: What is the difference to ShapeID()?"""
> > return self.shapeid
>
> RawData() returns the data for the shape in it's "raw" form. What that
> is depends on the shape store. For shapefiles it's the id, for the
> PostGISShape a string with the WKT representation. So, it's a
> coincidence that RawData() is identical to ShapeID(). The raw form is
> used by the low-level renderers, for instance, because it can increase
> performance substantially.
This explanation could have helped me if in a default Shape.RawData()
method ;-) Currently we do not have a suitable place in the code to
put this text.
--
Jan-Oliver Wagner http://intevation.de/~jan/
Intevation GmbH http://intevation.de/
FreeGIS http://freegis.org/
More information about the Thuban-devel
mailing list
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)