[Java-collab] Introduction and a few suggestions on recent topics

Markus Schneider schneider at lat-lon.de
Thu Aug 20 09:52:53 EDT 2009


Hi Matthias,

Matthias Basler wrote:

 > - Factory/Builder? Yes.
> 
> In order to support the above point of hiding the implementation from the user a factory and/or builder is required. And yes, it should be just one or a few classes to avoid the user having to search for the correct factory. (Of course, developers should be free to call "new XYZImpl()" if they want, but programmser *using* the library should not be required to know that XYZImpl exists!)

I second that. I also think it's just easier to be able to call "new DefaultEnvelope(0,0,1,1)" instead of being forced
to always instantiate or keep track of a factory. Of course, the factory plays a vital role as well and is definitely
needed, so users don't need to know the concrete implementation (and one can simplify the setting of common parameters,
such as the CRS or a precision model).

> In my case I arranged that the builder could be initialized with different "implementations" (i.e. produce two different types of geometry implementations)
> 
> I also equipped the builder with conversion functions (e.g. from JTS) for the convenience of the user. Depending on the geometry implementations the builder either actually converts the JTS object or just wraps it.
> 
> - Point/Envelope
> 
> Of course I also came across the question whether envelopes/bounds and coordinates are actually full-fledged geometries or not?
> My solution for this was to have a design like this:
> 
>   - IGeometry
>       (just any geometric object, includes CRS info)
>   - IFeatureGeometry extends IGeometry
>       (adds identifier and metadata)
>   - Abstract classes on top of each,
>     implementing shared functions
> 
> Geometric operations (like union, getBounds etc.) can be done with Geometry, but only IFeatureGeometry can actually be used in features, topologies etc.
> 
> Rectangular envelopes and coordinates would just implement IGeometry, but not IFeatureGeometry, and the rectangular envelope would not allow CRS transformations (for obvious mathematical reasons).

I think this is pretty similar to what we stumbled upon lately. We thought about having a (crudely-named, I must admit)
top-level interface EnvelopeOrGeometry.

> - CRS usage in operations
> 
> My preference is to perform CRS transformations where they can be implemented most efficiently - in the geometry implementation.
> 
> Therefore I chose to do geometry transformation "on the fly", with the CRS of the initial geometry being the relevant one.
> So for geom1.union(geom2) the result would have the CRS of geom1. I also chose to allow an explicit target CRS when exporting to f.e. JTS or Java2D or when calculating the bounds of an object. IMHO more flexibility means more convenience for the user, in this case.
> 
> In any case: If the target CRS is the same (or not specified) optimizations kick in.

I also like the idea that a user does not need to think about the involved CRSes before she/he calls
geom1.intersects(geom2).

> - Axis order
> 
> I tried to be VERY explicit here. So I used getOrdinate(), getOrd1(), getSpan() and so on, which accept the CRS axis order, and also stored the coordinates accordingly.
> 
> BUT for the convenience of the user I also added getX() (and so on) to the API and made it clear through the JavaDoc that getX() would return the actual value along the axis west-east, if the CRS defines such axis.
> (See below for the CRS discussion.)
> 
> So I now have the "generic" and a well-defined XY-based solution. The latter is handy for conversion from/to JTS and other such tasks.

Nice idea. But what happens when a Point has no CRS information at all? What does getX() return then?

> I also introduced a boolean "respectAxisOrder" flags to several methods to allow the API user to *explicitely* specify if f.e. an export to 2D JTS should keep an YX axis order (if defined so by the CRS) or should switch axes to XY in this case. IMHO this is better than making assumptions of what the user might want.

Interesting. However, I can imagine that this could actually become more confusing than just using the original axis
order. Can you give an example for such an operation?

> - CRS handling: CRSInfo suggestion
> 
> One problem was how to combine the following CRS requirements:
>   1.) Take up as few space in the geometry as possible
>       (memory efficiency)
>   2.) How to avoid duplicate computations (e.g. which axis is X)
>       (performance efficiency)
>   3.) Avoid code duplication
> 
> I put a low of thoughts in this, but finally came up with a simple, clean solution I am very happy with. I simple created an immutable wrapper around the immutable GeoAPI CRS object. I called it CRSInfo.
> 
> CRSInfo has several methods for getting the actual CRS, computing axis order, lenient axis order, CRS dimensions, computing 2D CRS from 3D CRS and others. All computed information is cached. When queried for its CRS, the geometry just returns
> myCRSInfo.getCRS().
> 
> Since CRSInfo is immutable I can easily share it between millions of geometries with almost no overhead. Each geometry only has a reference to its CRSInfo, no more. Assuming that an application uses only a handful of CRS at a time I even added a CRSInfo cache which further reduces duplicate computations.

Nice thinking. We also have a similar wrapper to solve two other CRS related issues. Taken from the javadoc:

> There are two aspects that this class takes care of:
> - In applications, coordinate reference system are usually identified using strings (such as 'EPSG:4326'). However, here are multiple equivalent ways to encode coordinate reference system identifications (another one would be 'urn:ogc:def:crs:EPSG::4326'). By using this class to represent a CRS, the original spelling is maintained.
> - A coordinate reference system may be specified which is not known to the {@link CRSRegistry}. However, for some operations this is not a necessarily a problem, e.g. a GML document may be read and transformed into {@link Feature} and {@link Geometry} objects.

> - CRS API/implementation
> 
> The point currently worrying me most in this project here is how you will cope with CRS API/implementation(s). (Yes, I have read the IRC logs.)
> 
> So far I chose GeoAPI with no doubt that this sound API would become the de-facto standard. Now people on this list tell me the opposite. I am worried, to say the least.
> 
> My preference from a user's POV would be to not have some "least common denominator" wrapper interface, but directly reference an established API like GeoAPI.
> 
> At latest when you do the operations you will have to define some specific API (for coordinate transformation and such) and then I will see what you'll come up with. I hope you find a solution that is easy to use (for a user) and still flexible enough to work for all involved parties.

Well, I hope so, too :-)

> - GeoAPI compatibility possible?
> 
> May I suggest that functions in the new geometry API get equal names as in GeoAPI if they *are* equal in definition and functions that are different (or return a different class, have a different contract etc.) get different names.
> 
> I'd definitely be pissed off (sorry) if it would not be possible to write a geometry class implementing both GeoAPI and your new API at the same time because of API method incompatibilities. But I fear this will happen (starting with getCRS() ...).
> 
> Obviously GeoAPI has more users that some here believe. ;-)

I definitely see your point. However, I think that we have should try to find a common denominator that allows the
different communities to work together in the first place. No one says, that we may not agree on more common parts (e.g.
CRS) in the future. I got the feeling that we would just block any achievements if we require to get this issue solved
right away. To me, the CRS representation does not seem to be relevant until we focus on operations. So, we may well
reach a first common goal (representation of arbitrary GML geometries) together, even if we have to split up at a later
point.

Anyway, thanks for the valuable input!

Best regards,
Markus


-- 
Markus Schneider

l a t / l o n  GmbH
Aennchenstrasse 19           53177 Bonn, Germany
phone ++49 +228 184960       fax ++49 +228 1849629
http://www.lat-lon.de        http://www.deegree.org

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 260 bytes
Desc: OpenPGP digital signature
Url : http://lists.osgeo.org/pipermail/java-collab/attachments/20090820/a61df94e/signature.bin


More information about the Java-collab mailing list