MathTransform and Projections

Topics: General Topics
Sep 8, 2008 at 10:47 AM
Hey all,

I've been playing around with the Coordinate Systems stuff in SharpMap and am encountering an interesting issue.  Am hoping someone here can explain what is happening and whether this is expected.

Take this code/class for example:

CoordinateSystemFactory CoordFact = new CoordinateSystemFactory();
ICoordinateTransformation Transformation = new CoordinateTransformationFactory().CreateFromCoordinateSystems(SourceCS, TargetCS);
return GeometryTransform.TransformGeometry(SourceGeometry, Transformation.MathTransform);

I provide the SourceCS and TargetCS variables and they are put through the CreateFromCoordinateSystems function to define how to do the transformation.  This transformation object is made up of a number of ConcatenatedTransform objects once complete, often 2-3.  These take the SourceCS into WGS84, then back from WGS84 to whatever the TargetCS is.  This all works fine, however often the 2D geometry objects (made up of 2D vertices) that get fed into the transformation get changed into 3D coordinates (as a result of changing datums and going through a geocentric coordinate system in one of the middle ConcatenedTransform steps). 

For example, a 2D coordinate such as (640000, 5814000) in a UTM Zone 55S on WGS84 system gets changed into a 3D coordinate (145.5, -37.5, 0.002) in Geographic AGD66 (the old Australian spheroid).  While there is clearly just a little bit of rounding or stuff going on here, the fact is that a list of double[2] objects go in and a lsit of double[3] objects come out. 

This then raises an exception in the Data\Point.cs class, as a point is only permitted to be 2D as a SharpMap Geometry.  So, for the moment, I've just modified the Point.cs class to permit a double[3] to get provided to create a point object, but it just ignores the last bit of the coordinate (i.e. the small Z/height that got produced through hte transformation process).  Does that sound reasonable to you guys out there?  Or do you think I am doing something wrong in my transformation process that needs to be fixed so that these small heights are not getting added into the coordinates in the first place.

Am interested to hear comments or questions about this.

Thanks, Steve
Sep 8, 2008 at 11:33 AM
I think this may be somewhat linked to a minor bug in the HorizontalDatum class in Proj.NET. 

In the EqualParams class, the last line does a comparison between the Ellipsoids using this line:

return datum.Ellipsoid == this.Ellipsoid && this.DatumType == datum.DatumType;

It returns false, even when the two Ellipsoids are identical.  But, changing it to read fixes up those problems:

return datum.Ellipsoid.EqualParams(this.Ellipsoid) && this.DatumType == datum.DatumType;

I think this should stop a bunch of redundant concatenated math transforms occurring between coordinate systems, which seems to be what produces the small heights getting put into the 2D coordinates.

Sep 9, 2008 at 5:28 AM
That Proj.NET returns double[3] is by design and does it for a good reason. SharpMap should handle it appropriately and I think you should log an issue.
However the comparison of datums is a bug. I've fixed it so go grab the source.