[Java-collab] geometry factory vs interface
Jorge Piera
jorge.piera at iver.es
Thu Aug 13 02:01:22 EDT 2009
Jody Garnett wrote:
>> I think that one of the main goals of this project has to be to define
>> an API for geometries and the usage of Interfaces is normally more
>> flexible that the usage of abstract classes. I always prefer to define a
>> Interface and a default implementation for this Interface.
>>
>> In the proposal of interfaces that Markus did I've seen methods like:
>>
>> - public boolean isBeyond( Geometry geometry, Measure distance );
>> - public boolean isWithin( Geometry geometry );
>> - public boolean overlaps( Geometry geometry );
>> - ...
>>
>> that are not refered to the geometry structure. They are operations! We
>> have to separate structure of functionality and I suggest that all these
>> methods have not to be here.
>>
>> In gvSIG we have replaced all these methods by just one:
>>
>> - public Object invokeOperation(int index, GeometryOperationContext ctx)
>>
>> Details can be found here [1]. Yes, we know that we are losing
>> performance with this option but we are winning in other issues:
>
> I like it Jorge - now you are playing with fire :-)
>
> I would actually like a compromise for usability here ... I would like
> something like the following (don't pick on the example too much since
> I am thinking as I type :D ).
>
> /**
> * Test if we are a set distance beyond another geometry.
> * <p>
> * This is a connivence method for the following call:<pre><code>
> * return invokeOperation( BeyondOperationContext( this, geom,
> distance ));</code></pre>
> * <p>
> * @geom Geometry to check against; care should be taken that it is in
> the same CRS
> * @geom distance distance to check from geom
> * @returns true if distance beyond the indicated geom.
> */
> public boolean isBeyond( Geometry geom, Measure distance );
> /**
> public boolean invokeOperation( BooleanOperationContext );
>
> public Geometry union( Geometry geom );
> public Geometry invokeOperation( GeometryOperationContext );
>
> Indeed I would rather *not* have the "invokeOperation" as part of the
> Geometry; since I expect to have a switch board of operations to
> choose from based on the geometry involved; CRS being used and so on.
>
> Jorge are you familiar with the operation split in JTS? The recent
> operation for PrepairedGeometry construct? It is used to hold onto
> intermediate results (edge graphs and so on). This is what I envision
> for a GeometryOperationContext ...
No, I'm not familiar but I'm going to have a look.
>> - The Geometry Interface is always the same (we don't have the problem
>> that has been commented above).
>> - Using this system is possible to provide a new implementation of one
>> concrete operation associated to a GeometryType and it is not necessary
>> to update the GeometryType (separation between structure and
>> functionality).
>>>> Especially, for Point and Envelope I would also like to have
>>>> constructors alternatively to a factory:
>>>>
>>>> Point p = new Point (0,1);
>>>>
>>>> is just nicer to write than
>>>>
>>>> GeometryFactory.getInstance().createPoint (0,1);
>>>
>>> You have highlighted one place where I was sure I would need an
>>> interface :-) Indeed when a Points data structure provides access to
>>> a single Point it often would use a light weight implementation of
>>> Point that would delegate onto the backing double[] for example. Or
>>> another implementation could make use of a List<PointImpl> etc... I
>>> see later in this email you talk about recycling a Point object when
>>> iterating; to accomplish this you will need to define Point as a
>>> data object and add equals and hashcode to the interface.
>> Point has to be always an Interface. We can have the classes Point2D,
>> Point3D.... and we can not make a "new" of any of them. We can maybe use
>> the Builder pattern to provide different sets of geometries.
>>
>> In gvSIG it is possible to add your own implementation of GeometryType
>> separately and we have a "GeometryManager" to create them:
>>
>> Point point = geometryManager.createPoint(2);
>>
>> 2 is the dimension of the geometry. We have a faster way to create a
>> point in 2 dimensions using the method:
>>
>> Point point = geometryManager.createPoint(0,1, 2);
>>
>> It works because a "point in 2 dimensions" has been previously
>> registered on our manager and everyone can register its own
>> implementation of a Point2D.
>
> Interesting; we have selection of geometry factory implementations.
> And a GeometryBuilder that will hunt down the correct factory for the
> CRS you are building against (so we don;t say 2 - we let that part
> come from the CRS definition). In anycase that is neither here nor
> there .. we have come up with a similar design.
It looks an interesting approach the usage of the CRS. But there is a
small detail that I hid in my last email to simplify the example. Really
we don't use "2" to define the dimension. We use a set on constants in
our application to classify our geometries:
- GEOM2D
- GEOM2DZ
- GEOM2M
- GEOM3D
- GEOM3DM
"M" means the "M coordinate". In a future we also can add geometries
with Time or other classes of geometries. If you only uses the CRS is
not possible to specify if you want a geometry with support for the M
coordinate.
>
> One thing I found *bad* about this design in geotools is that we had
> too many small factories; indeed a GeometryBuilder was kind of needed
> since it was a pain to hunt down the correct AggregateFactory,
> PositionFactory, PrecisionFactory, ComplexFactory and GeometryFactory :-)
>
> So some kind of balance would be good; I imagine this is something we
> can sort out with live code examples when the time comes?
>
> Just to bury my original point:
> - we *could* make use of classes for Geometry; as long as we have the
> invokeOperation stuff isolated behind interfaces.
> - it is probably only useful as an extreme to force us to think about
> what we are doing
> - please consider the geotools implementation of many little factories
> as the other extreme
>
> With that in mind Jorge - how are you actually getting along with your
> approach? Is there anything that "boiler plate" or hard to do? I could
> see making a bunch of calls to register stuff with your
> geometryManager - and just cutting and pasting that code against and
> again; just so I did not have to *think* when creating points.
I suppose that with Geotools I can register my own set of factories to
create my own geometries. Cool! The difference is that we can register
single geometries: e.g: I can register my own implementation for a Point
with 2 dimensions, and I only have to register the class that implements it.
It is true that you have to do a bunch of calls to register all the
geometries in the GeometryManager, but I think that it is not any
problem: this code is written just one time and in the 99% of the times
is not necessary to update it. Only if you want to add your own geometry
you have to register it.
It is just other approach.
Best regards,
Jorge.
--
Jorge Piera Llodrá
Especialista en Servicios OGC
Equipo de desarrollo gvSIG
IVER TI S.A.
C/ Lérida, 20
46009-Valencia (Spain)
Tlf.+34902252540
www.iver.es
www.gvsig.com
More information about the Java-collab
mailing list