[Java-collab] CRS axis issues (Was: Introduction and a few suggestions on recent topics)

Matthias Basler matthiasbasler at earthflight.org
Thu Aug 20 15:10:45 EDT 2009


Markus Schneider wrote:

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

I don't have this use case. But good you bring up this question. My opinion is: A geometry without CRS is *useless* in a GIS system and should not be allowed.
I mean, without a CRS...
- you cannot draw the features because you don't even know whether their coordinates are on perpendicular axes or are spherical coordinates
- you don't know if two such features having similar coordinates are actually at the same place or not even near each other.

You an only *assume* some CRS (be it a "real" geographic/projected CRS or just a generic perpendicular XYZ coordinate system), and in this case you could as well attach this assumed CRS to the geometry instead of having a "null" CRS.

As a consequence, a GIS application usually has have a "default CRS". This could be handled in the factory, which could add the default CRS if non is specified in the input arguments for creating the geometry.

But back to getX(), getY() and getZ():
I suggest to only return values here if the CRS actually uses perpendicular axes corresponding to
- west/east, south/north and down/up
- DISPLAY_LEFT/~RIGHT and DISPLAY_UP/~DOWN
- maybe even GEOCENTRIC_X/~Y/~Z 
or subsets thereof. I would throw an exception in any other case, e.g. for polar coordinates. This gives the caller a possibility to discover that he/she is likely about to do something stupid. ;-)
Being too lenient with getX() and getY() will create only confusion, as the GeoTools developers know by experience.

> 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?

You provide it yourself: "... than just using the original axis".

If I take my preference of "X must actually mean west/east/x" as a base then creating a JTS geometry (which only knows X,Y and Z) can mean that
(a) the coordinate axes might need swapping
(c) it will throw an exception for polar coordinates or the like, since it isn't built for working with polar coordinates as X and Y.

You prefer the opposite, which is to assume that JTS X/Y correspond to axis 1 and 2. This can equally make sense for internal implementations of union operations and the like where the axis order of intermediate objects is often irrelevant for the result and not swapping the axes back and forth can improve the computational speed. 

So for methods like "toJTS(...)" we have two choices:
- Give the programmer the ability to specify
  how he wants the resulting axes OR
- Decide on one of the choices, document it well and
  hold on it throughout the API.

I'm for flexibility. Imho it won't make the API difficult to understand if the choice and its implications are *well documented*. A good API is not necessarily the one with the shortest method signatures, but one that is well documented and consistent!

(P.S. This is also why I think that get1(), get2() are short, but not necessarily intuitive for newbies. I came up with getOrd1(), getOrd2() as compromise. But it's not a big issue for me.)

> 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 good idea.

> > - 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.

Do I understand you correctly?
Having a CRS identifier but not knowing how the CRS is defined? Difficult matter, this:

I mean, some operations like union between two such geometries should be possible, but interactions between geometries without/with a known CRS are undefined. Neither will it be possible to draw a map with them.

How should this be handled? Should the geometries throw errors in such cases? Or should they be lenient and use the "default CRS" (like above) in such cases, even if this is not the correct one?

Keeping the original "specified" CRS information seems reasonable in any case.


Hmm...
Somehow I wonder if there shouldn't be a global flag for "strict" CRS handling? I personally prefer a strict handling and I'd rather not allow any operations bases in unfounded assumptions CRS wise. Better not have a result than have one that's useless because wrong. Lenient solutions should not be handled in the geometry library but on an application level (like switching to another CRS when the application discovers that the data uses opposite axis order than specified in the CRS).

But I could imagine others here have opposite practical experiences.

Sorry for the long mail again.
-- 
Matthias Basler
matthiasbasler at earthflight.org



More information about the Java-collab mailing list